Class: MijDiscord::Core::Gateway

Inherits:
Object
  • Object
show all
Defined in:
lib/mij-discord/core/gateway.rb

Constant Summary collapse

GATEWAY_VERSION =
6
LARGE_THRESHOLD =
100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot, auth, shard_key = nil) ⇒ Gateway

Returns a new instance of Gateway.



113
114
115
116
117
118
119
120
# File 'lib/mij-discord/core/gateway.rb', line 113

def initialize(bot, auth, shard_key = nil)
  @bot, @auth, @shard_key = bot, auth, shard_key

  @ws_success = false
  @getc_mutex = Mutex.new

  @check_heartbeat_acks = true
end

Instance Attribute Details

#check_heartbeat_acksObject

Returns the value of attribute check_heartbeat_acks.



111
112
113
# File 'lib/mij-discord/core/gateway.rb', line 111

def check_heartbeat_acks
  @check_heartbeat_acks
end

Instance Method Details

#heartbeatObject



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/mij-discord/core/gateway.rb', line 170

def heartbeat
  if check_heartbeat_acks
    unless @last_heartbeat_acked
      MijDiscord::LOGGER.warn('Gateway') { 'Heartbeat not acknowledged, attempting to reconnect' }

      @broken_pipe = true
      reconnect(true)
      return
    end

    @last_heartbeat_acked = false
  end

  send_heartbeat(@session&.sequence || 0)
end

#killObject



155
156
157
158
# File 'lib/mij-discord/core/gateway.rb', line 155

def kill
  @ws_thread&.kill
  nil
end

#notify_readyObject



274
275
276
# File 'lib/mij-discord/core/gateway.rb', line 274

def notify_ready
  @ws_success = true
end

#open?Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/mij-discord/core/gateway.rb', line 160

def open?
  @handshake&.finished? && !@ws_closed
end

#reconnect(try_resume = true) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'lib/mij-discord/core/gateway.rb', line 186

def reconnect(try_resume = true)
  @session&.suspend if try_resume

  @instant_reconnect = true
  @should_reconnect = true

  ws_close(false)
  nil
end

#run_asyncObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/mij-discord/core/gateway.rb', line 122

def run_async
  @ws_thread = Thread.new do
    Thread.current[:mij_discord] = 'websocket'

    @reconnect_delay = 1.0

    loop do
      ws_connect

      break unless @should_reconnect

      if @instant_reconnect
        @reconnect_delay = 1.0
        @instant_reconnect = false
      else
        sleep(@reconnect_delay)
        @reconnect_delay = [@reconnect_delay * 1.5, 120].min
      end
    end

    MijDiscord::LOGGER.info('Gateway') { 'Websocket loop has been terminated' }
  end

  sleep(0.2) until @ws_success
  MijDiscord::LOGGER.info('Gateway') { 'Connection established and confirmed' }
  nil
end

#send_heartbeat(sequence) ⇒ Object



196
197
198
# File 'lib/mij-discord/core/gateway.rb', line 196

def send_heartbeat(sequence)
  send_packet(Opcodes::HEARTBEAT, sequence)
end

#send_identify(token, properties, compress, large_threshold, shard_key) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/mij-discord/core/gateway.rb', line 200

def send_identify(token, properties, compress, large_threshold, shard_key)
  data = {
    token: token,
    properties: properties,
    compress: compress,
    large_threshold: large_threshold,
  }

  data[:shard] = shard_key if shard_key

  send_packet(Opcodes::IDENTIFY, data)
end

#send_packet(opcode, packet) ⇒ Object



259
260
261
262
263
264
265
266
267
# File 'lib/mij-discord/core/gateway.rb', line 259

def send_packet(opcode, packet)
  data = {
    op: opcode,
    d: packet,
  }

  ws_send(data.to_json, :text)
  nil
end

#send_raw(data, type = :text) ⇒ Object



269
270
271
272
# File 'lib/mij-discord/core/gateway.rb', line 269

def send_raw(data, type = :text)
  ws_send(data, type)
  nil
end

#send_request_guild_sync(guilds) ⇒ Object



255
256
257
# File 'lib/mij-discord/core/gateway.rb', line 255

def send_request_guild_sync(guilds)
  send_packet(Opcodes::GUILD_SYNC, guilds)
end

#send_request_members(server_id, query = '', limit = 0) ⇒ Object



245
246
247
248
249
250
251
252
253
# File 'lib/mij-discord/core/gateway.rb', line 245

def send_request_members(server_id, query = '', limit = 0)
  data = {
    guild_id: server_id,
    query: query,
    limit: limit,
  }

  send_packet(Opcodes::REQUEST_MEMBERS, data)
end

#send_resume(token, session_id, sequence) ⇒ Object



235
236
237
238
239
240
241
242
243
# File 'lib/mij-discord/core/gateway.rb', line 235

def send_resume(token, session_id, sequence)
  data = {
    token: token,
    session_id: session_id,
    seq: sequence,
  }

  send_packet(Opcodes::RESUME, data)
end

#send_status_update(status, since, game, afk) ⇒ Object



213
214
215
216
217
218
219
220
221
222
# File 'lib/mij-discord/core/gateway.rb', line 213

def send_status_update(status, since, game, afk)
  data = {
    status: status,
    since: since,
    game: game,
    afk: afk,
  }

  send_packet(Opcodes::PRESENCE, data)
end

#send_voice_state_update(server_id, channel_id, self_mute, self_deaf) ⇒ Object



224
225
226
227
228
229
230
231
232
233
# File 'lib/mij-discord/core/gateway.rb', line 224

def send_voice_state_update(server_id, channel_id, self_mute, self_deaf)
  data = {
    guild_id: server_id,
    channel_id: channel_id,
    self_mute: self_mute,
    self_deaf: self_deaf,
  }

  send_packet(Opcodes::VOICE_STATE, data)
end

#stop(no_sync = false) ⇒ Object



164
165
166
167
168
# File 'lib/mij-discord/core/gateway.rb', line 164

def stop(no_sync = false)
  @should_reconnect = false
  ws_close(no_sync)
  nil
end

#syncObject



150
151
152
153
# File 'lib/mij-discord/core/gateway.rb', line 150

def sync
  @ws_thread&.join
  nil
end