private void PeerTimerCallback(object state) { if (!disconnecting && connection != null && connection.State == HubConnectionState.Connected && Me != null) { if (!string.IsNullOrEmpty(MessageToken) && DateTime.UtcNow > MessageTokenValidTo) { EnsureMessageToken().Wait(); } if (Me.LastStatusTime + Me.StatusExpirationTimeout > DateTime.UtcNow - TimeSpan.FromSeconds(SelfStatusTimeMarginInSeconds)) { Me.LastStatusTime = DateTime.UtcNow; SendMessageToAll("STILL_HERE", Me.Status.ToString(), true); } foreach (SignalNowPeer peer in Peers.Values) { if (peer.Status != PeerStatus.Offline) { if (peer.LastStatusTime + peer.StatusExpirationTimeout < DateTime.UtcNow) { #if UNITY_2018_2_OR_NEWER UnityEngine.Debug.Log($"{peer.UserId} status expired."); #else System.Diagnostics.Debug.WriteLine($"{peer.UserId} status expired."); #endif peer.Status = PeerStatus.Offline; PeerStatusChanged?.Invoke(this, peer); } } } } }
private void OnMessageIn(string senderId, string messageType, string messagePayload) { if (disconnecting) { return; } DateTime messageTime = DateTime.UtcNow; if (messageType.Equals("I_AM_HERE", StringComparison.InvariantCultureIgnoreCase)) { TimeSpan statusExpirationTimeout = TimeSpan.FromSeconds(int.Parse(messagePayload)); bool newPeer = true; if (peers.ContainsKey(senderId)) { newPeer = false; peers[senderId].Resurrect(); PeerStatusChanged?.Invoke(this, peers[senderId]); } string response = $"[\"{(int)Me.StatusExpirationTimeout.TotalSeconds}\", \"{Me.Status.ToString()}\"]"; SendImportantMessage(senderId, false, "HELLO", response, true) .ContinueWith((res) => { if (newPeer) { peers[senderId] = new SignalNowPeer(senderId, PeerStatus.Online, statusExpirationTimeout); NewPeer?.Invoke(this, peers[senderId]); } }); } else if (messageType.Equals("HELLO", StringComparison.InvariantCultureIgnoreCase)) { JArray paramArray = JArray.Parse(messagePayload); var timeoutStr = paramArray[0].ToString(); var statusStr = paramArray[1].ToString(); TimeSpan statusExpirationTimeout = TimeSpan.FromSeconds(int.Parse(timeoutStr)); PeerStatus status = (PeerStatus)Enum.Parse(typeof(PeerStatus), statusStr, true); if (!peers.ContainsKey(senderId)) { peers[senderId] = new SignalNowPeer(senderId, status, statusExpirationTimeout); NewPeer?.Invoke(this, peers[senderId]); } else { peers[senderId].LastStatusTime = messageTime; peers[senderId].Status = status; peers[senderId].StatusExpirationTimeout = statusExpirationTimeout; PeerStatusChanged?.Invoke(this, peers[senderId]); } } else if (messageType.Equals("I_AM_OUTTA_HERE", StringComparison.InvariantCultureIgnoreCase)) { if (peers.ContainsKey(senderId)) { peers[senderId].Status = PeerStatus.Offline; PeerStatusChanged?.Invoke(this, peers[senderId]); #if UNITY_2018_2_OR_NEWER UnityEngine.Debug.Log($"{senderId} quit."); #else System.Diagnostics.Debug.WriteLine($"{senderId} quit."); #endif } } else { // only respect messages from peers we had a handshake with if (peers.ContainsKey(senderId)) { peers[senderId].LastDataMessageTime = messageTime; peers[senderId].LastStatusTime = messageTime; if (messageType.Equals("STILL_HERE", StringComparison.InvariantCultureIgnoreCase)) { PeerStatus status = (PeerStatus)Enum.Parse(typeof(PeerStatus), messagePayload, true); peers[senderId].Status = status; } else { Task.Run(() => { NewMessage?.Invoke(this, senderId, messageType, messagePayload); }); } } } }