public WebSocketServer(IPAddress ip, ushort port, ConfWebSocket confWebSocket) { this.ip = ip ?? throw new ArgumentException("No IP address provided."); if (port == 0) { throw new ArgumentException("Invalid port 0 provided."); } this.port = port; this.confWebSocket = confWebSocket; if (this.confWebSocket.JwsKey == "DefaultKey") { Log.Warn("Default key in use for websocket JWS. This might not even work and is at least a bad idea."); } running = true; ConnectedClients = new ConcurrentDictionary <int, WebSocketConnection>(); newConnectionHandlerThread = new Thread(NewConnectionHandler) { IsBackground = true }; newConnectionHandlerThread.Start(); var clientWatcherThread = new Thread(() => { while (running) { IList <int> keysToRemove = new List <int>(); foreach (var pair in ConnectedClients) { if (!pair.Value.IsRunning()) { keysToRemove.Add(pair.Key); } } foreach (var key in keysToRemove) { ConnectedClients.TryRemove(key, out var client); client?.Stop(); } Thread.Sleep(1000); } }) { IsBackground = true }; clientWatcherThread.Start(); }
public WebSocketPipe(ConfWebSocket confWebSocket) { server = new WebSocketServer(IPAddress.Loopback, 2020, confWebSocket); }
public UpdateWebSocket( KDFCommandsPlugin kdf, Player player, PlayManager playManager, ResolveContext resolver, Ts3Client ts3Client, TsFullClient ts3FullClient, ConfWebSocket confWebSocket ) { this.kdf = kdf; this.player = player; this.playManager = playManager; this.resolver = resolver; this.ts3Client = ts3Client; this.ts3FullClient = ts3FullClient; this.playManager.Queue.OnQueueChange += QueueChanged; this.playManager.Queue.OnQueueIndexChange += UpdateRecentlyPlayed; this.kdf.Autofill.OnStateChange += AutofillChanged; this.kdf.Voting.OnSkipVoteChanged -= SkipVoteChanged; server = new WebSocketServer(IPAddress.Loopback, 2021, confWebSocket); server.OnClientConnected += ClientConnected; running = true; var thread = new Thread(() => { JsonValue <Dictionary <string, IList <(string, string)> > > listeners = null; JsonValue <SongInfo> song = null; bool frozen = false; long frozenSince = -1; while (running) { // Check for listener change var newListeners = KDFCommandsPlugin.CommandListeners(ts3Client, ts3FullClient, player); if (listeners == null || !ListenersEqual(listeners, newListeners)) { SendListenerUpdate(newListeners); } listeners = newListeners; // Check if song should be updated JsonValue <SongInfo> newSong = null; try { newSong = MainCommands.CommandSong(playManager, player, resolver); } catch (CommandException) { // Don't crash just because nothing is playing } if (newSong != null) { var ts = DateTimeOffset.Now.ToUnixTimeMilliseconds(); bool frozenStateChanged = ts - player.WebSocketPipe.LastDataSentTimestamp > 500 != frozen; if (frozenStateChanged) { frozen = !frozen; frozenSince = frozen ? DateTimeOffset.Now.ToUnixTimeSeconds() : -1; } if ( song == null || newSong.Value.Position < song.Value.Position || newSong.Value.Length != song.Value.Length || newSong.Value.Link != song.Value.Link || newSong.Value.Paused != song.Value.Paused || frozenStateChanged && !frozen ) { if (Log.IsTraceEnabled) { string reason = "Unexpected reason."; if (song == null) { reason = "First song started playing."; } else if (newSong.Value.Position < song.Value.Position) { reason = "Position < previous position."; } else if (newSong.Value.Length != song.Value.Length) { reason = "Length changed."; } else if (newSong.Value.Link != song.Value.Link) { reason = "Resource URL changed."; } else if (newSong.Value.Paused != song.Value.Paused) { reason = "Pause state changed."; } else if (frozenStateChanged & !frozen) { reason = "Song was frozen for over 500ms and now unfroze."; } Log.Trace("Song update sent. Reason: " + reason); } SendSongUpdate(newSong); } // Send resync update if frozen every 5 seconds. if (frozen && (DateTimeOffset.Now.ToUnixTimeSeconds() - frozenSince) % 5 == 4) { Log.Trace("Song update sent. Reason: Update in frozen state."); SendSongUpdate(newSong); } } else if (song != null) { // newSong is null but previous song was not --> music stopped SendToAll("song", null); Log.Trace("Song update sent. Reason: Music stopped."); } song = newSong; Thread.Sleep(1000); } }) { IsBackground = true }; thread.Start(); }