/// <summary> /// 处理过期的客户端 /// </summary> /// <param name="expiredClientList"></param> private void HandleExpiredClients(IList <ITcpClientProxy> expiredClientList) { if (expiredClientList != null) { for (int index = expiredClientList.Count - 1; index >= 0; index--) { var clientHandler = expiredClientList[index]; _logger.Error(string.Format("BusinessId为{0}的学生机心跳超时,将断开接连。", clientHandler.BusinessID)); // 通知外部事件 try { if (this.ClientDisconnected != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(clientHandler.ReceiveContext); stateObject.ClientStatus = ClientStateEnums.Closed; this.ClientDisconnected(this, stateObject); } } catch (Exception ex) { // 外部未处理的异常,记录日志,不影响主流程。 _logger.Error(ex.StackTrace); } this.RecycleContext(clientHandler.ReceiveContext); } } }
// 客户端断开 protected virtual void OnClientDisconnected(SocketAsyncEventArgs e) { if (this.ClientDisconnected != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(e); this.ClientDisconnected(this, stateObject); } }
// 向客户端发送消息后 protected virtual void OnMessageSend(SocketAsyncEventArgs e) { if (this.MessageSend != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(e); stateObject.ClientStatus = ClientStateEnums.Connected; this.MessageSend(this, stateObject); } }
// 从客户端接收消息后 protected virtual void OnMessageReceived(SocketAsyncEventArgs e) { if (this.MessageReceived != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(e); stateObject.ClientStatus = ClientStateEnums.Connected; this.MessageReceived(this, stateObject); // 保存服务器要返回给客户端的消息(临时) stateObject.ClientProxy.ExchangedData = stateObject.ResponseMessage; } }
/// <summary> /// 处理错误操作 /// </summary> /// <param name="e"></param> private void ProcessError(SocketAsyncEventArgs e) { ITcpClientProxy handler = e.UserToken as ITcpClientProxy; if (!handler.IsDisposed) { lock (handler) { if (handler.IsDisposed) { return; } Console.WriteLine("{0} 出错了,回收之。{1} : {2}", e.RemoteEndPoint, e.LastOperation, e.SocketError ); _logger.Error(string.Format("回收了一个客户端{0}。{1} : {2}", e.RemoteEndPoint, e.LastOperation, e.SocketError)); if (handler != null && handler.ClientStatus != (int)ClientStateEnums.Closed) { handler.ClientStatus = (int)ClientStateEnums.Closed; // 通知外部事件 if (this.ClientDisconnected != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(e); stateObject.ClientStatus = ClientStateEnums.Closed; this.ClientDisconnected(this, stateObject); } this.RecycleContext(e); } handler.Dispose(); } } }
/// <summary> /// 停止侦听服务. /// </summary> public void Stop() { _logger.Info("主动关闭TCP, 断开接连。"); // 先通知所有客户端断开 if (_clientMembers != null) { for (int index = _clientMembers.Count - 1; index >= 0; index--) { var clientHandler = _clientMembers[index]; try { if (this.ClientDisconnected != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(clientHandler.ReceiveContext); stateObject.ClientStatus = ClientStateEnums.Closed; this.ClientDisconnected(this, stateObject); } //_clientHandlers.Remove(clientHandler); } catch (Exception ex) { // 外部未处理的异常,记录日志,不影响主流程。 _logger.Error(ex.StackTrace); } //this.RecycleContext(clientHandler.ReceiveContext); } } lock (_tcpLock) { // 1.pulse thread close this.StopCheckingPulse(); // 清理缓存,事件 SocketAsyncEventArgs eventArgs; while (this._poolOfAcceptEventArgs.Count > 0) { eventArgs = _poolOfAcceptEventArgs.Pop(); eventArgs.Completed -= SocketAsyncEventArgs_IOCompleted; //_bufferManager.FreeBuffer(eventArgs); eventArgs.Dispose(); } while (this._poolOfReadWriteEventArgs.Count > 0) { eventArgs = _poolOfReadWriteEventArgs.Pop(); eventArgs.Completed -= SocketAsyncEventArgs_IOCompleted; _bufferManager.FreeBuffer(eventArgs); eventArgs.Dispose(); } _bufferManager = null; //GC.Collect(); try { //_socketListener.Disconnect(true); //_socketListener.Shutdown(SocketShutdown.Both); } catch (Exception ex) { _logger.Error(ex.StackTrace); } finally { if (_socketListener != null) { _socketListener.Close(); _socketListener.Dispose(); _socketListener = null; } } mutex.ReleaseMutex(); this._semaphoreAcceptedClients.Release(); // 清掉当前客户端 foreach (var client in _clientMembers) { Socket s = client.Connection; try { s.Close(); //s.Shutdown(SocketShutdown.Receive); //s.Disconnect(true); } catch (Exception) { } finally { if (s.Connected) { s.Close(); s.Dispose(); } s = null; } } _clientMembers.Clear(); } }