private void OnClosed(object sender, CloseEventArgs args) { Log($"Closed. Code: {args.Code}, reason: {args.Reason}"); State = MediaSessionState.StandBy; if (args.Code == 1006) { Thread.Sleep(200); } // so far i've only seen code 1000 being used because of an invalid session but still gonna reconnect to be safe var code = (DiscordMediaCloseCode)args.Code; if (args.Code == 1000 || args.Code == 1006 || code == DiscordMediaCloseCode.SessionTimeout || code == DiscordMediaCloseCode.ServerCrashed) { Task.Run(() => Connect()); } else { if (args.Code != (ushort)UnorthodoxCloseCode.KeepQuiet) { Task.Run(() => HandleDisconnect(new DiscordMediaCloseEventArgs(code, args.Reason))); } } }
internal void UpdateServer(DiscordMediaServer server) { CurrentServer = server; Log($"Set server to {server.Endpoint}"); State = MediaSessionState.StandBy; if (server.Endpoint != null && WebSocket != null) { Log("Changing server"); Task.Run(() => Connect()); } if (OnServerUpdated != null) { Task.Run(() => OnServerUpdated.Invoke(this, server)); } }
// If u connect to a vc in the same server as ur previous, ur connection won't die // It makes no sense to then manually kill it bcuz that's extra time // There's a chance that the client will miss events. A low one, but quite possible internal DiscordMediaSession(DiscordMediaSession other) : this(other.Client, other.GuildId, other.ChannelId, other.SessionId) { WebSocket = other.WebSocket; WebSocket.OnClosed += OnClosed; WebSocket.OnMessageReceived += OnMessageReceived; other.State = MediaSessionState.Dead; other.OnServerUpdated = null; other.WebSocket.OnMessageReceived -= OnMessageReceived; other.WebSocket.OnClosed -= OnClosed; _serverEndpoint = other._serverEndpoint; _localEndpoint = other._localEndpoint; UdpClient = other.UdpClient; SSRC = other.SSRC; SecretKey = other.SecretKey; SessionId = other.SessionId; CurrentServer = other.CurrentServer; ReceivePackets = other.ReceivePackets; State = other.State; }
public void Connect() { Log($"Connecting to {CurrentServer.Endpoint}"); if (State == MediaSessionState.Authenticated) { Task.Run(() => HandleConnect()); } else { State = MediaSessionState.Connecting; WebSocket?.Close((ushort)UnorthodoxCloseCode.KeepQuiet, "Killing old websocket"); WebSocket = new MediaWebSocket("wss://" + CurrentServer.Endpoint + "?v=4", this); WebSocket.OnClosed += OnClosed; WebSocket.OnMessageReceived += OnMessageReceived; WebSocket.SetProxy(Client.Proxy); WebSocket.Connect(); } }
private void OnMessageReceived(object sender, DiscordWebSocketMessage <DiscordMediaOpcode> message) { try { switch (message.Opcode) { case DiscordMediaOpcode.Ready: DiscordMediaReady ready = message.Data.ToObject <DiscordMediaReady>(); SSRC = new DiscordSSRC() { Audio = ready.SSRC }; _serverEndpoint = new IPEndPoint(IPAddress.Parse(ready.IP), ready.Port); UdpClient = new UdpClient(); UdpClient.Connect(_serverEndpoint); Task.Run(() => StartListener()); Holepunch(); break; case DiscordMediaOpcode.SessionDescription: var description = message.Data.ToObject <DiscordSessionDescription>(); if (ValidateCodecs(description)) { if (description.EncryptionMode != Sodium.EncryptionMode) { Disconnect(DiscordMediaCloseCode.InvalidEncryptionMode, "Unexpected encryption mode: " + description.EncryptionMode); } else { SecretKey = description.SecretKey; State = MediaSessionState.Authenticated; Log("Authenticated"); Task.Run(() => HandleConnect()); } } break; case DiscordMediaOpcode.ChangeCodecs: // apparently this triggers whenever u switch channel // im confused //var codecs = message.Data.ToObject<MediaCodecSelection>(); break; case DiscordMediaOpcode.Hello: WebSocket.Send(DiscordMediaOpcode.Identify, new DiscordMediaIdentify() { ServerId = GetServerId(), UserId = Client.User.Id, SessionId = Client.SessionId, Token = CurrentServer.Token, Video = true }); WebSocket.StartHeartbeaterAsync(message.Data.Value <int>("heartbeat_interval")); break; default: HandleMessage(message); break; } } catch (InvalidOperationException) { } }