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); } }
//========== 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 MatchCtrl m_MatchCtrl; //比赛系统 public SystemFacade() { m_AccountCtrl = new AccountCtrl(); m_SelectGameCtrl = new GameCtrl(); m_RuleCtrl = new RuleCtrl(); m_ServiceCtrl = new ServiceCtrl(); m_SettingCtrl = new SettingCtrl(); m_ShareCtrl = new ShareCtrl(); m_RecordCtrl = new RecordCtrl(); m_ShopCtrl = new ShopCtrl(); m_PresentCtrl = new PresentCtrl(); m_MahJongCtrl = new MaJiangGameCtrl(); m_ChatCtrl = new ChatCtrl(); m_AudioSettingCtrl = new AudioSettingCtrl(); m_NoticeCtrl = new NoticeCtrl(); m_MatchCtrl = new MatchCtrl(); RegisterWindow(); }
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 }); }