/// <summary> /// 处理tcp client断开事件 /// </summary> /// <param name="connection">SocketConnectionInfo</param> internal void DisconnectClient(SocketConnectionInfo connection) { OnClientDisconnecting.RaiseEvent(null, CreateSocketSeesion(connection, null)); if (connection.Socket != null) { connection.Socket.BeginDisconnect(true, new AsyncCallback(ClientDisconnected), connection); } }
public void Update() { if (m_state == ManagerState.Connected && m_prevState == ManagerState.Connecting) { // client just connected: invoke event handlers OnClientConnected?.Invoke(); } else if (!m_connectionRequested && m_prevState == ManagerState.Connected) { // client about to disconnect: invoke event handlers OnClientDisconnecting?.Invoke(); // transition to actual disconnect m_state = ManagerState.Disconnecting; } if (m_client.IsConnected()) { // process server updates and events here so entity updates are processed in the render loop m_client.ProcessServerUpdates(); } // relay events to handlers in render loop: // registered clients lock (m_registeredClients) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingClients.AddRange(m_registeredClients); m_registeredClients.Clear(); } if (m_processingClients.Count > 0) { // process newly registered client events foreach (ClientData client in m_processingClients) { OnClientRegistered?.Invoke(client); } m_processingClients.Clear(); } // unregistered clients lock (m_unregisteredClients) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingClients.AddRange(m_unregisteredClients); m_unregisteredClients.Clear(); } if (m_processingClients.Count > 0) { // process newly unregistered client events foreach (ClientData client in m_processingClients) { OnClientUnregistered?.Invoke(client); } m_processingClients.Clear(); } // publishing entities lock (m_publishedEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_publishedEntities); m_publishedEntities.Clear(); } if (m_processingEntities.Count > 0) { // process published entity events OnEntitiesPublished?.Invoke(m_processingEntities); m_processingEntities.Clear(); } // revoking entities lock (m_revokedEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_revokedEntities); m_revokedEntities.Clear(); } if (m_processingEntities.Count > 0) { // process revoked entity events OnEntitiesRevoked?.Invoke(m_processingEntities); m_processingEntities.Clear(); } lock (m_controlledEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_controlledEntities); m_controlledEntities.Clear(); } if (m_processingEntities.Count > 0) { // process control-changed entity events OnEntityControlChanged?.Invoke(m_processingEntities); m_processingEntities.Clear(); } // broadcasts lock (m_broadcasts) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingBroadcasts.AddRange(m_broadcasts); m_broadcasts.Clear(); } if (m_processingBroadcasts.Count > 0) { // handle broadcasts foreach (Broadcast broadcast in m_processingBroadcasts) { OnClientBroadcastReceived?.Invoke(broadcast); } m_processingBroadcasts.Clear(); } lock (m_serverShutdown) { if (m_serverShutdown.Count > 0) { bool restart = m_serverShutdown[0]; OnServerShutdown?.Invoke(restart); StartCoroutine(AutoDisconnectAsync(restart)); m_serverShutdown.Clear(); } } m_prevState = m_state; }
protected override void OnDisconnecting(OfClientConnection connection) { LogInfo($"[{connection.Mac}] Disconnected."); OnClientDisconnecting?.Invoke(connection); }