class Slack::RealTime::Client
def build_socket
-
(Slack::RealTime::Socket)
-
def build_socket fail 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_class.new(@url, socket_options) end
def callback(event, type)
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 e false end
def close(_event)
def close(_event) socket = @socket @socket = nil [socket, socket_class].each do |s| s.close if s.respond_to?(:close) end end
def config
def config Config end
def configure
def configure block_given? ? yield(config) : config end
def dispatch(event)
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.class}##{__method__}") { data.to_s } run_handlers(type, data) if @store run_callbacks(type, data) rescue StandardError => e logger.error e false end
def initialize(options = {})
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
def on(type, &block)
def on(type, &block) type = type.to_s callbacks[type] << block end
def open(_event)
def open(_event) end
def rtm_start_method
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
def run_callbacks(type, data)
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 e false end
def run_handlers(type, data)
def run_handlers(type, data) handlers = store.class.events[type.to_s] handlers.each do |handler| store.instance_exec(data, &handler) end if handlers rescue StandardError => e logger.error e false end
def run_loop
def run_loop @socket.connect! do |driver| @callback.call(driver) if @callback driver.on :open do |event| logger.debug("#{self.class}##{__method__}") { event.class.name } open(event) callback(event, :open) end driver.on :message do |event| logger.debug("#{self.class}##{__method__}") { "#{event.class}, #{event.data}" } dispatch(event) end driver.on :close do |event| logger.debug("#{self.class}##{__method__}") { event.class.name } callback(event, :close) close(event) callback(event, :closed) end end end
def send_json(data)
def send_json(data) fail ClientNotStartedError unless started? logger.debug("#{self.class}##{__method__}") { data } @socket.send_data(data.to_json) end
def socket_class
def socket_class concurrency::Socket end
def socket_options
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
def start!(&block)
def start!(&block) @callback = block if block_given? @socket = build_socket @socket.start_sync(self) end
def start_async(&block)
Start RealTime client and return immediately.
def start_async(&block) @callback = block if block_given? @socket = build_socket @socket.start_async(self) end
def started?
def started? @socket && @socket.connected? end
def stop!
def stop! fail ClientNotStartedError unless started? @socket.disconnect! if @socket end