Exemplo n.º 1
0
        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();
        }
Exemplo n.º 2
0
 public WebSocketPipe(ConfWebSocket confWebSocket)
 {
     server = new WebSocketServer(IPAddress.Loopback, 2020, confWebSocket);
 }
Exemplo n.º 3
0
        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();
        }