예제 #1
0
        public void Stop()
        {
            Socket socket = this._socket;

            lock (this._receivedDatas)
            {
                if (this._socket == null)
                {
                    return;
                }
                this._socket = null;
                this._receivedDatas.Clear();

                int count = this._tokens.Count;
                for (int i = 0; i < count; i++)
                {
                    TCPUserToken token = this._tokens[i];
                    this.OnSocketEvent?.Invoke(new SocketEvent(SocketEvent.Type.Disconnect, "Server stoped", SocketError.Shutdown, token));
                    token.Close();
                    this._userTokenPool.Push(token);
                }
                this._tokens.Clear();
                this._idToTokens.Clear();
            }

            if (socket.Connected)
            {
                socket.Shutdown(SocketShutdown.Both);
            }
            socket.Close();
        }
예제 #2
0
        public void Update(long dt)
        {
            this._updateContext.deltaTime = dt;
            this._updateContext.time     += dt;

            this.ProcessReceiveDatas();
            this.CheckClientOverRange();

            int count = this._tokens.Count;

            for (int i = 0; i < count; i++)
            {
                TCPUserToken token = this._tokens[i];
                if (token.disconnectEvent == null)
                {
                    continue;
                }
                this.OnSocketEvent?.Invoke(token.disconnectEvent.Value);
                token.Close();
                this._tokens.RemoveAt(i);
                this._idToTokens.Remove(token.id);
                this._userTokenPool.Push(token);
                --i;
                --count;
            }
            if (this._closeEvent != null)
            {
                this.OnSocketEvent?.Invoke(this._closeEvent.Value);
                this._closeEvent = null;
                this.Stop();
            }
        }
예제 #3
0
        internal void ProcessReceive(SocketAsyncEventArgs receiveEventArgs)
        {
            TCPUserToken token = ( TCPUserToken )receiveEventArgs.UserToken;

            if (receiveEventArgs.SocketError != SocketError.Success)
            {
                token.MarkToDisconnect($"Receive error, remote endpoint: {token.remoteEndPoint}",
                                       receiveEventArgs.SocketError);
                return;
            }
            int size = receiveEventArgs.BytesTransferred;

            if (size == 0)
            {
                token.MarkToDisconnect($"Receive zero bytes, remote endpoint: {token.remoteEndPoint}", SocketError.NoData);
                return;
            }
            lock (this._receivedDatas)
            {
                if (this._socket != null)
                {
                    token.CacheData(receiveEventArgs.Buffer, receiveEventArgs.Offset, receiveEventArgs.BytesTransferred);
                    this._receivedDatas.Push(new ReceivedData(token));
                }
            }
            this.StartReceive(token);
        }
예제 #4
0
        private void CheckClientOverRange()
        {
            int over = this._tokens.Count - this._maxClient;

            for (int i = 0; i < over; i++)
            {
                TCPUserToken token = this._tokens[this._tokens.Count - 1];
                token.MarkToDisconnect($"Client overrange, remote endpoint: {token.remoteEndPoint}",
                                       SocketError.SocketError);
            }
        }
예제 #5
0
        private void ProcessReceiveDatas()
        {
            this._receivedDatas.Switch();
            while (!this._receivedDatas.isEmpty)
            {
                ReceivedData receivedData = this._receivedDatas.Pop();
                switch (receivedData.type)
                {
                case ReceivedData.Type.Accept:
                {
                    TCPUserToken newToken = this._userTokenPool.Pop(this);
                    this._tokens.Add(newToken);
                    this._idToTokens.Add(newToken.id, newToken);
                    newToken.OnAccepted(receivedData.conn, TimeUtils.utcTime);
                    this.OnSocketEvent?.Invoke(new SocketEvent(SocketEvent.Type.Accept,
                                                               $"Client connection accepted, remote endpoint: {receivedData.conn.RemoteEndPoint}",
                                                               SocketError.Success, newToken));
                    this.StartReceive(newToken);
                    newToken.Send(new PacketAccept(newToken.id));
                }
                break;

                case ReceivedData.Type.Receive:
                {
                    TCPUserToken token = ( TCPUserToken )receivedData.token;
                    token.ProcessData(packet =>
                        {
                            if (packet.module == NetworkConfig.INTERNAL_MODULE && packet.command == 0)
                            {
                                token.Send(new PacketHeartBeat((( PacketHeartBeat )packet).localTime));
                            }
                            else
                            {
                                this.OnSocketEvent?.Invoke(new SocketEvent(SocketEvent.Type.Receive, packet, token));
                            }
                        });
                }
                break;
                }
            }
        }
예제 #6
0
        private void StartReceive(TCPUserToken token)
        {
            bool asyncResult;

            try
            {
                asyncResult = token.ReceiveAsync(token.receiveEventArgs);
            }
            catch (ObjectDisposedException)
            {
                return;
            }
            catch (SocketException e)
            {
                token.MarkToDisconnect($"Receive error:{e}, remote endpoint: {token.remoteEndPoint}", e.SocketErrorCode);
                return;
            }
            if (!asyncResult)
            {
                this.ProcessReceive(token.receiveEventArgs);
            }
        }
예제 #7
0
 public void Push(TCPUserToken token)
 {
     this._pool.Enqueue(token);
 }