class Slack::RealTime::Client
Attributes
events[RW]
callbacks[R]
store[RW]
url[RW]
web_client[RW]
Public Class Methods
config()
click to toggle source
# File lib/slack/real_time/client.rb, line 77 def config Config end
configure() { |config| ... }
click to toggle source
# File lib/slack/real_time/client.rb, line 73 def configure block_given? ? yield(config) : config end
new(options = {})
click to toggle source
# File lib/slack/real_time/client.rb, line 26 def initialize(options = {}) @callbacks = Hash.new { |h, k| h[k] = [] } Slack::RealTime::Config::ATTRIBUTES.each do |key| send("#{key}=", options.key?(key) ? options[key] : Slack::RealTime.config.send(key)) end @token ||= Slack.config.token @logger ||= (Slack::Config.logger || Slack::Logger.default) @web_client = Slack::Web::Client.new(token: token, logger: logger) end
Public Instance Methods
keep_alive?()
click to toggle source
Ensure the server is running, and ping the remote server if no other messages were sent.
# File lib/slack/real_time/client.rb, line 108 def keep_alive? # We can't ping the remote server if we aren't connected. return false if @socket.nil? || !@socket.connected? time_since_last_message = @socket.time_since_last_message # If the server responded within the specified time, we are okay: return true if time_since_last_message < websocket_ping # If the server has not responded for a while: return false if time_since_last_message > (websocket_ping * 2) # Kick off the next ping message: ping true end
on(type, &block)
click to toggle source
# File lib/slack/real_time/client.rb, line 42 def on(type, &block) type = type.to_s callbacks[type] << block end
run_loop()
click to toggle source
# File lib/slack/real_time/client.rb, line 82 def run_loop @socket.connect! do |driver| driver.on :open do |event| logger.debug("#{self}##{__method__}") { event.class.name } open_event(event) callback(event, :open) end driver.on :message do |event| logger.debug("#{self}##{__method__}") { "#{event.class}, #{event.data}" } dispatch(event) end driver.on :close do |event| logger.debug("#{self}##{__method__}") { event.class.name } callback(event, :close) close(event) callback(event, :closed) end # This must be called last to ensure any events are registered before invoking user code. @callback&.call(driver) end end
run_ping!()
click to toggle source
Check if the remote server is responsive, and if not, restart the connection.
# File lib/slack/real_time/client.rb, line 127 def run_ping! return if keep_alive? logger.warn(to_s) { 'is offline' } restart_async rescue Slack::Web::Api::Errors::SlackError => e # stop pinging if bot was uninstalled case e.message when 'account_inactive', 'invalid_auth' then logger.warn(to_s) { e.message } raise e end logger.debug("#{self}##{__method__}") { e } rescue StandardError => e # disregard all ping worker failures, keep pinging logger.debug("#{self}##{__method__}") { e } end
run_ping?()
click to toggle source
# File lib/slack/real_time/client.rb, line 146 def run_ping? !websocket_ping.nil? && websocket_ping.positive? end
start!(&block)
click to toggle source
Start RealTime
client and block until it disconnects.
# File lib/slack/real_time/client.rb, line 48 def start!(&block) @callback = block if block_given? build_socket @socket.start_sync(self) end
start_async(&block)
click to toggle source
Start RealTime
client and return immediately. The RealTime::Client
will run in the background.
# File lib/slack/real_time/client.rb, line 56 def start_async(&block) @callback = block if block_given? build_socket @socket.start_async(self) end
started?()
click to toggle source
# File lib/slack/real_time/client.rb, line 68 def started? @socket&.connected? end
stop!()
click to toggle source
# File lib/slack/real_time/client.rb, line 62 def stop! raise ClientNotStartedError unless started? @socket&.disconnect! end
to_s()
click to toggle source
Calls superclass method
# File lib/slack/real_time/client.rb, line 154 def to_s if store&.team "id=#{store.team.id}, name=#{store.team.name}, domain=#{store.team.domain}" else super end end
websocket_ping_timer()
click to toggle source
# File lib/slack/real_time/client.rb, line 150 def websocket_ping_timer websocket_ping / 2 end
Protected Instance Methods
build_socket()
click to toggle source
@return [Slack::RealTime::Socket]
# File lib/slack/real_time/client.rb, line 175 def build_socket raise ClientAlreadyStartedError if started? start = web_client.send(rtm_start_method, start_options) data = Slack::Messages::Message.new(start) @url = data.url @store = @store_class.new(data) if @store_class @socket = socket_class.new(@url, socket_options) end
callback(event, type)
click to toggle source
# File lib/slack/real_time/client.rb, line 223 def callback(event, type) callbacks = self.callbacks[type.to_s] return false unless callbacks callbacks.each do |c| c.call(event) end true rescue StandardError => e logger.error("#{self}##{__method__}") { e } false end
close(_event)
click to toggle source
# File lib/slack/real_time/client.rb, line 217 def close(_event) [@socket, socket_class].each do |s| s.close if s.respond_to?(:close) end end
dispatch(event)
click to toggle source
# File lib/slack/real_time/client.rb, line 236 def dispatch(event) return false unless event.data data = Slack::Messages::Message.new(JSON.parse(event.data)) type = data.type return false unless type type = type.to_s logger.debug("#{self}##{__method__}") { data.to_s } run_handlers(type, data) if @store run_callbacks(type, data) rescue StandardError => e logger.error("#{self}##{__method__}") { e } false end
open_event(_event)
click to toggle source
# File lib/slack/real_time/client.rb, line 215 def open_event(_event); end
restart_async()
click to toggle source
# File lib/slack/real_time/client.rb, line 164 def restart_async logger.debug("#{self}##{__method__}") @socket.close start = web_client.send(rtm_start_method, start_options) data = Slack::Messages::Message.new(start) @url = data.url @store = @store_class.new(data) if @store_class @socket.restart_async(self, @url) end
rtm_start_method()
click to toggle source
# File lib/slack/real_time/client.rb, line 185 def rtm_start_method if start_method start_method elsif @store_class && @store_class <= Slack::RealTime::Stores::Store :rtm_start else :rtm_connect end end
run_callbacks(type, data)
click to toggle source
# File lib/slack/real_time/client.rb, line 264 def run_callbacks(type, data) callbacks = self.callbacks[type] return false unless callbacks callbacks.each do |c| c.call(data) end true rescue StandardError => e logger.error("#{self}##{__method__}") { e } false end
run_handlers(type, data)
click to toggle source
# File lib/slack/real_time/client.rb, line 252 def run_handlers(type, data) return unless store.class.events handlers = store.class.events[type.to_s] handlers&.each do |handler| store.instance_exec(data, &handler) end rescue StandardError => e logger.error("#{self}##{__method__}") { e } false end
send_json(data)
click to toggle source
# File lib/slack/real_time/client.rb, line 208 def send_json(data) raise ClientNotStartedError unless started? logger.debug("#{self}##{__method__}") { data } @socket.send_data(data.to_json) end
socket_class()
click to toggle source
# File lib/slack/real_time/client.rb, line 204 def socket_class concurrency::Socket end
socket_options()
click to toggle source
# File lib/slack/real_time/client.rb, line 195 def socket_options socket_options = {} socket_options[:ping] = websocket_ping if websocket_ping socket_options[:proxy] = websocket_proxy if websocket_proxy socket_options[:logger] = logger socket_options end