protected ClientContext AddNewClient(Socket newClient) { ClientContext context = null; if (_clientContextPool == null) { context = new ClientContext(); context.SockAsyncArgs = new SocketAsyncEventArgs(); byte[] asyncBuffer = new byte[_tcpConfig.SocketAsyncBufferSize]; context.SockAsyncArgs.SetBuffer(asyncBuffer, 0, asyncBuffer.Length); } else { context = _clientContextPool.Pop(); } context.ClientSocket = newClient; context.ClientID = (long)newClient.Handle; context.Status = ClientStatus.Connected; if (_tcpConfig.ReceiveDataMaxSpeed != TcpConfig.NotLimited) { context.RecvSpeedController.LimitSpeed = _tcpConfig.ReceiveDataMaxSpeed; context.RecvSpeedController.Enabled = true; } if (_tcpConfig.SendDataMaxSpeed != TcpConfig.NotLimited) { context.SendController.LimitSpeed = _tcpConfig.SendDataMaxSpeed; context.SendController.Enabled = true; } context.SockAsyncArgs.Completed += SockAsyncArgs_Completed; IPEndPoint remoteIPEnd = (IPEndPoint)newClient.RemoteEndPoint; //save original ip end point, so we can always get the remote ip end point even the socket is closed. context.IPEndPoint = new IPEndPoint(remoteIPEnd.Address, remoteIPEnd.Port); bool bOK = _clients.TryAdd((long)newClient.Handle, context); if (this is TcpClientEx) { System.Diagnostics.Trace.Assert(bOK, $"client:add new client failed:{this.GetHashCode()} {newClient.Handle}"); } else { System.Diagnostics.Trace.Assert(bOK, $"server:add new client failed:{this.GetHashCode()} {newClient.Handle}"); } context.SockAsyncArgs.UserToken = (long)newClient.Handle; ClientStatusChangedEventArgs eventArgs = new ClientStatusChangedEventArgs() { ClientID = context.ClientID, IPEndPoint = newClient.RemoteEndPoint as IPEndPoint, Status = ClientStatus.Connected }; OnClientStatusChanged(false, eventArgs, null); if (!newClient.ReceiveAsync(context.SockAsyncArgs)) { ProcessReceive(context.SockAsyncArgs); } return(context); }
protected override void OnClientStatusChanged(bool isInThread, ClientStatusChangedEventArgs args, HashSet <string> clientGroups) { if (args.Status == ClientStatus.Closed) { RemoveClientFromGroup(args.ClientID, clientGroups); } ClientStatusChanged?.Invoke(this, args); }
protected override void OnClientStatusChanged(bool isInThread, ClientStatusChangedEventArgs args, HashSet <string> groups) { ClientStatus status = args.Status; if (status == ClientStatus.Connected) { SetStatusAndNotify(status); } else if (status == ClientStatus.Closed) { if (!_autoReconnect) { _isRunning = false; //if (isInThread) //{ // _syncContext.Post((state) => // { // SetStatusAndNotify(ClientStatus.Closed); // }, null); //} //else //{ // SetStatusAndNotify(ClientStatus.Closed); //} SetStatusAndNotify(ClientStatus.Closed); } else { if (!_isRunning) { SetStatusAndNotify(ClientStatus.Closed); //_syncContext.Post((state) => //{ // SetStatusAndNotify(ClientStatus.Closed); //}, null); return; } SetStatusAndNotify(ClientStatus.Connecting); //_syncContext.Post((state) => //{ // AfterConnect(false); //SetStatusAndNotify(ClientStatus.Connecting); ThreadEx.Start(() => { //reconnect to server 2 seconds later _reconnectWaitEvent.WaitOne(2000); if (_isRunning) { InitClientSocket(); ConnectAsyncInner(null); } }); //}, null); } } }
private void SetStatusAndNotify(ClientStatus status) { if (status == _clientStatus) { return; } _clientStatus = status; var args = new ClientStatusChangedEventArgs() { ClientID = _clientID, IPEndPoint = (IPEndPoint)_serverEndPoint, Status = _clientStatus }; Task.Factory.StartNew((obj) => { ClientStatusChanged?.Invoke(this, (ClientStatusChangedEventArgs)obj); }, args); }
protected void CloseClient(bool isInThread, long clientID) { if (_clients.TryRemove(clientID, out ClientContext clientContext)) { IPEndPoint ipEndPt = clientContext.IPEndPoint; clientContext.Status = ClientStatus.Closed; clientContext.ClientSocket.Close(); clientContext.ClientSocket.Dispose(); clientContext.SockAsyncArgs.Completed -= SockAsyncArgs_Completed; ClientStatusChangedEventArgs eventArgs = new ClientStatusChangedEventArgs() { ClientID = clientID, IPEndPoint = ipEndPt, Status = ClientStatus.Closed }; OnClientStatusChanged(isInThread, eventArgs, clientContext.Groups); if (_clientContextPool != null) { clientContext.Reset(); _clientContextPool.Push(clientContext); } } }
protected virtual void OnClientStatusChanged(bool isInThread, ClientStatusChangedEventArgs args, HashSet <string> clientGroups) { }