//========== 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); } }
private void PublishHealthReport() { var chatState = ChatCtrl.GetState(); var report = new { HubAliveConnections = _heartBeat.GetConnections().Count, UsersConnectionsCount = UsersConnections.Count, UsersConnectionsValuesCount = UsersConnections.Values.Count, RoomsConnectionsCount = RoomsConnections.Count, RoomsConnectionsValuesCount = RoomsConnections.ValuesCount, ChatAllUsersCount = chatState.AllUsers.Count, ChatRoomsCounts = chatState.Rooms.Count, ChatRoomsUsersCounts = chatState.Rooms.Values.Sum(list => list.Count), ManagedQueuesCount, UnackedManagedQueuesCount, FullDetails = new { HubAliveConnections = _heartBeat.GetConnections().Select(conn => new { conn.ConnectionId, conn.IsAlive, conn.IsTimedOut }), UsersConnections = UsersConnections.All, RoomsConnections = RoomsConnections.All } }; Log.SignalR(LogTag.ChatHubHealthReport, new { report }); }