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.



27
28
29
30
31
32
33
34
35
# File 'lib/slack/real_time/client.rb', line 27

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

#loggerObject

Returns the value of attribute logger.



23
24
25
# File 'lib/slack/real_time/client.rb', line 23

def logger
  @logger
end

#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



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

def config
  Config
end

.configureObject



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

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)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/slack/real_time/client.rb', line 109

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



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

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

#run_loopObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/slack/real_time/client.rb', line 83

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.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/slack/real_time/client.rb', line 128

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)


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

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

#start!(&block) ⇒ Object

Start RealTime client and block until it disconnects.



49
50
51
52
53
# File 'lib/slack/real_time/client.rb', line 49

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.



57
58
59
60
61
# File 'lib/slack/real_time/client.rb', line 57

def start_async(&block)
  @callback = block if block_given?
  build_socket
  @socket.start_async(self)
end

#started?Boolean

Returns:

  • (Boolean)


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

def started?
  @socket&.connected?
end

#stop!Object



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

def stop!
  raise ClientNotStartedError unless started?

  @socket&.disconnect!
end

#to_sObject



155
156
157
158
159
160
161
# File 'lib/slack/real_time/client.rb', line 155

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



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

def websocket_ping_timer
  websocket_ping / 2
end