예제 #1
0
        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);
        }
예제 #2
0
 protected override void OnClientStatusChanged(bool isInThread, ClientStatusChangedEventArgs args, HashSet <string> clientGroups)
 {
     if (args.Status == ClientStatus.Closed)
     {
         RemoveClientFromGroup(args.ClientID, clientGroups);
     }
     ClientStatusChanged?.Invoke(this, args);
 }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 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);
         }
     }
 }
예제 #6
0
 protected virtual void OnClientStatusChanged(bool isInThread, ClientStatusChangedEventArgs args, HashSet <string> clientGroups)
 {
 }