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);
            }
        }
Example #3
0
    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 });
        }