Class: OnyxCord::Voice::VoiceWS
- Inherits:
-
Object
- Object
- OnyxCord::Voice::VoiceWS
- Defined in:
- lib/onyxcord/voice/network/websocket.rb
Constant Summary collapse
- VOICE_GATEWAY_VERSION =
The version of the voice gateway that's supposed to be used.
8
Instance Attribute Summary collapse
-
#udp ⇒ VoiceUDP
readonly
The UDP voice connection over which the actual audio data is sent.
Instance Method Summary collapse
-
#connect ⇒ Object
Communication goes like this: me discord | | websocket connect -> | | | | <- websocket opcode 2 | | UDP discovery -> | | | | <- UDP reply packet | | websocket opcode 1 -> | | | ...
-
#destroy(join_timeout = 1) ⇒ Object
Disconnects the websocket and kills the thread.
-
#initialize(channel, bot, token, session, endpoint) ⇒ VoiceWS
constructor
Makes a new voice websocket client, but doesn't connect it (see #connect for that).
-
#send_heartbeat ⇒ Object
Send a heartbeat (op 3), has to be done every @heartbeat_interval seconds or the connection will terminate.
-
#send_init(server_id, bot_user_id, session_id, token) ⇒ Object
Send a connection init packet (op 0).
- #send_opcode(opcode, data) ⇒ Object
-
#send_speaking(value) ⇒ Object
Send a speaking packet (op 5).
-
#send_udp_connection(ip, port, mode) ⇒ Object
Sends the UDP connection packet (op 1).
Constructor Details
#initialize(channel, bot, token, session, endpoint) ⇒ VoiceWS
Makes a new voice websocket client, but doesn't connect it (see #connect for that)
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 17 def initialize(channel, bot, token, session, endpoint) raise 'libsodium is unavailable - unable to create voice bot! Please read https://github.com/kruldevb/OnyxCord/wiki/Installing-libsodium' unless LIBSODIUM_AVAILABLE @channel = channel @bot = bot @token = token @session = session @endpoint = endpoint @udp = VoiceUDP.new end |
Instance Attribute Details
#udp ⇒ VoiceUDP (readonly)
Returns the UDP voice connection over which the actual audio data is sent.
9 10 11 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 9 def udp @udp end |
Instance Method Details
#connect ⇒ Object
Communication goes like this: me discord | | websocket connect -> | | | | <- websocket opcode 2 | | UDP discovery -> | | | | <- UDP reply packet | | websocket opcode 1 -> | | | ...
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 161 def connect # Connect websocket @thread = Thread.new do Thread.current[:onyxcord_name] = 'vws' init_ws end @bot.debug('Started websocket initialization, now waiting for UDP discovery reply') # Now wait for opcode 2 and the resulting UDP reply packet ip, port = @udp.receive_discovery_reply @bot.debug("UDP discovery reply received! #{ip} #{port}") # Send UDP init packet with received UDP data send_udp_connection(ip, port, @udp_mode) @bot.debug('Waiting for op 4 now') # Wait for op 4, then finish @ready_mutex ||= Mutex.new @ready_condition ||= ConditionVariable.new @ready_mutex.synchronize do @ready_condition.wait(@ready_mutex, 30) unless @ready end end |
#destroy(join_timeout = 1) ⇒ Object
Disconnects the websocket and kills the thread
188 189 190 191 192 193 194 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 188 def destroy(join_timeout = 1) @heartbeat_running = false @client&.close @udp.close @thread&.join(join_timeout) @thread&.kill if @thread&.alive? end |
#send_heartbeat ⇒ Object
Send a heartbeat (op 3), has to be done every @heartbeat_interval seconds or the connection will terminate
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 66 def send_heartbeat millis = (Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)).to_i @bot.debug("Sending voice heartbeat at #{millis}") send_opcode( Opcodes::HEARTBEAT, { t: millis, seq_ack: @seq } ) end |
#send_init(server_id, bot_user_id, session_id, token) ⇒ Object
Send a connection init packet (op 0)
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 35 def send_init(server_id, bot_user_id, session_id, token) send_opcode( Opcodes::IDENTIFY, { server_id: server_id, user_id: bot_user_id, session_id: session_id, token: token } ) end |
#send_opcode(opcode, data) ⇒ Object
92 93 94 95 96 97 98 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 92 def send_opcode(opcode, data) @bot.debug("Sending voice opcode #{opcode} with data: #{data}") @client.send({ op: opcode, d: data }.to_json) end |
#send_speaking(value) ⇒ Object
Send a speaking packet (op 5). This determines the green circle around the avatar in the voice channel
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 81 def send_speaking(value) @bot.debug("Speaking: #{value}") send_opcode( Opcodes::SPEAKING, { speaking: value, delay: 0 } ) end |
#send_udp_connection(ip, port, mode) ⇒ Object
Sends the UDP connection packet (op 1)
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/onyxcord/voice/network/websocket.rb', line 51 def send_udp_connection(ip, port, mode) send_opcode( Opcodes::SELECT_PROTOCOL, { protocol: 'udp', data: { address: ip, port: port, mode: mode } } ) end |