private void ProcessWelcomeResponse(WelcomeResponse resp) { int heartbeatInterval = resp.d.heartbeat; if (heartbeatThread != null) { cts.Cancel(); //Running on the websocket thread, so no need to async/await heartbeatThread.Join(); } cts = new CancellationTokenSource(); heartbeatThread = new Thread(() => { Stopwatch watch = new Stopwatch(); watch.Start(); long lastMillis = watch.ElapsedMilliseconds; while (!cts.IsCancellationRequested) { long currentMillis = watch.ElapsedMilliseconds; if (currentMillis - lastMillis > heartbeatInterval) { SendHeartbeat(); lastMillis = currentMillis; } Thread.Sleep(1000); } }); heartbeatThread.Start(); }
private void ParseSongInfo(string data) { string noWhitespaceData = new string(data.Where(c => !Char.IsWhiteSpace(c)).ToArray()); if (noWhitespaceData.Contains("\"op\":0")) { //Identify/Welcome response WelcomeResponse resp = JsonConvert.DeserializeObject <WelcomeResponse>(data); ProcessWelcomeResponse(resp); } else if (noWhitespaceData.Contains("\"op\":1")) { //Song info SongInfoResponse resp = JsonConvert.DeserializeObject <SongInfoResponse>(data); if (resp.t != "TRACK_UPDATE") { return; } currentInfo = resp.d; currentInfo.song.sources = currentInfo.song.sources ?? new Source[0]; foreach (var source in currentInfo.song.sources) { source.name = Clean(source.name); source.nameRomaji = Clean(source.nameRomaji); } foreach (var artist in currentInfo.song.artists) { artist.name = Clean(artist.name); artist.nameRomaji = Clean(artist.nameRomaji); } currentInfo.song.title = Clean(currentInfo.song.title); if (currentInfo.requester != null) { currentInfo.requester.displayName = Clean(currentInfo.requester.displayName); currentInfo.requester.username = Clean(currentInfo.requester.username); } if (currentInfo._event != null) { currentInfo._event = Clean(currentInfo._event); } factory.StartNew(() => { OnSongInfoReceived(currentInfo); }); } }