Class: Slack::RealTime::Client

Inherits:
Object
  • Object
show all
Includes:
Api::Message, Api::MessageId, Api::Ping, Api::Typing
Defined in:
lib/slack/real_time/client.rb

Defined Under Namespace

Classes: ClientAlreadyStartedError, ClientNotStartedError

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Api::Typing

#typing

Methods included from Api::Message

#message

Methods included from Api::Ping

#ping

Constructor Details

#initialize(options = {}) ⇒ Client

Returns a new instance of Client.



26
27
28
29
30
31
32
33
34
# 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

Class Attribute Details

.eventsObject

Returns the value of attribute events.



16
17
18
# File 'lib/slack/real_time/client.rb', line 16

def events
  @events
end

Instance Attribute Details

#storeObject

Returns the value of attribute store.



20
21
22
# File 'lib/slack/real_time/client.rb', line 20

def store
  @store
end

#urlObject

Returns the value of attribute url.



21
22
23
# File 'lib/slack/real_time/client.rb', line 21

def url
  @url
end

#web_clientObject

Returns the value of attribute web_client.



19
20
21
# File 'lib/slack/real_time/client.rb', line 19

def web_client
  @web_client
end

Class Method Details

.configObject



77
78
79
# File 'lib/slack/real_time/client.rb', line 77

def config
  Config
end

.configureObject



73
74
75
# File 'lib/slack/real_time/client.rb', line 73

def configure
  block_given? ? yield(config) : config
end

Instance Method Details

#keep_alive?Boolean

Ensure the server is running, and ping the remote server if no other messages were sent.

Returns:

  • (Boolean)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 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) ⇒ Object



42
43
44
45
# File 'lib/slack/real_time/client.rb', line 42

def on(type, &block)
  type = type.to_s
  callbacks[type] << block
end

#run_loopObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 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!Object

Check if the remote server is responsive, and if not, restart the connection.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# 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?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/slack/real_time/client.rb', line 146

def run_ping?
  !websocket_ping.nil? && websocket_ping.positive?
end

#start!(&block) ⇒ Object

Start RealTime client and block until it disconnects.



48
49
50
51
52
# 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) ⇒ Object

Start RealTime client and return immediately. The RealTime::Client will run in the background.



56
57
58
59
60
# 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?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/slack/real_time/client.rb', line 68

def started?
  @socket&.connected?
end

#stop!Object



62
63
64
65
66
# File 'lib/slack/real_time/client.rb', line 62

def stop!
  raise ClientNotStartedError unless started?

  @socket&.disconnect!
end

#to_sObject



154
155
156
157
158
159
160
# 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_timerObject



150
151
152
# File 'lib/slack/real_time/client.rb', line 150

def websocket_ping_timer
  websocket_ping / 2
end