public virtual void CleanConnection(string connectionId) { Log.SignalR(LogTag.TextChatHub_CleaningConnection, new { connectionId }); // Remove Message Queue for this connection. Queues are created only when needed, so they might not always exists if (MessageQueues.ContainsKey(connectionId)) { MessageQueues[connectionId].Reset(); MessageQueues.Remove(connectionId); } // Remove all connections to rooms RoomsConnections.RemoveConnectionFromAllRooms(connectionId); // Remove User's Connection, and leave chat if this was the last connection if (UsersConnections.ContainsValue(connectionId)) { UserId userId = UsersConnections.GetFromValue(connectionId); UsersConnections.Remove(connectionId); if (!UsersConnections.ContainsKey(userId)) { ChatCtrl.LeaveChat(userId); } } else { Log.Info(LogTag.TextChatHub_AlreadyCleaned); } // Also remove LastSeen Info for this connection if (LastSeenConnections.ContainsKey(connectionId)) { LastSeenConnections.Remove(connectionId); } }
public void SignIn(string name) { lock (_lockObj10) { UsersConnections.Add(Context.ConnectionId, name); UsersNames.Add(name, Context.ConnectionId); foreach (var user in UsersWithStatus.Where(u => u.UserName == name)) { user.Status = StatusOfConnection.Available; } UpdateAllUsersNamesAndConnectionStatus(); } }
//========== Background Methods ====================================================================================== private void HeartbeatCheck() { try { // Try catch needed because errors are otherwised silenced, somehow :-( // Remove dead connections (Ping not received timely) foreach (var kvp in LastSeenConnections.ToList()) { if (kvp.Value < DateTime.Now.AddSeconds(-CleanZombieAfter)) { var connectionId = kvp.Key; Log.SignalR(LogTag.CleaningZombieConnection, new { connectionId }); CleanConnection(connectionId); } } // Remove inactive members from "crowded" rooms var chatState = ChatCtrl.GetState(); foreach (var roomKvp in chatState.Rooms) { if (roomKvp.Key.IsMonoLang() && roomKvp.Value.Count > BootAboveUserCount) { var mostInactiveUserKvp = roomKvp.Value.Aggregate((l, r) => l.Value.LastActive < r.Value.LastActive ? l : r); if (mostInactiveUserKvp.Value.LastActive < DateTime.Now.AddMinutes(-BootOutOfRoomAfter)) { Log.SignalR(LogTag.KickSlackerOutOfRoom, new { roomId = roomKvp.Key, userId = mostInactiveUserKvp.Key }); // Get the list of connections that have to leave the room var userConnectionIds = UsersConnections.GetFromKey(mostInactiveUserKvp.Key) .Where(connId => RoomsConnections.HasConnection(roomKvp.Key, connId)) .Select(connId => connId.ToString()).ToList(); Clients.Clients(userConnectionIds).LeaveRoom(roomKvp.Key); } } } // Check for inactive members foreach (var chatUser in chatState.AllUsers.Values) { if (chatUser.LastActivity < DateTime.Now.AddMinutes(-UserIdleAfter)) { ChatCtrl.SetIdleStatus(chatUser.Id); Log.SignalR(LogTag.SetChatUserIdle, new { userId = chatUser.Id }); } } Log.SignalR(LogTag.HubHeartbeatCheckCompleted); } catch (Exception e) { Log.Error(LogTag.HeartbeatCheckError, e); } }
public override Task OnDisconnected(bool stopCalled) { if (stopCalled) { var con = Context.ConnectionId; string nameToRemove = UsersConnections[con]; UsersNames.Remove(nameToRemove); UsersConnections.Remove(Clients.Caller); foreach (var item in UsersWithStatus) { if ((item.UserName).Equals(nameToRemove)) { item.Status = StatusOfConnection.Offline; } } UpdateAllUsersNamesAndConnectionStatus(); } return(base.OnDisconnected(stopCalled)); }
//========== Connection Helpers ====================================================================================== // Get users's connections to the chat private IEnumerable <ConnectionId> GetUserConnections(UserId partnerId) { return(UsersConnections.GetFromKey(partnerId)); }