Exemplo n.º 1
0
        private async void HandleClientConnection(TcpClient client)
        {
            var endpoint = client.Client.RemoteEndPoint;

            Debug.Log("Player connection request from {0}", endpoint);
            client.ReceiveBufferSize = 1024;
            client.SendBufferSize    = 1024;
            client.NoDelay           = true;
            client.LingerState       = new LingerOption(true, 10);

            Player player = null;

            try
            {
                using (var networkStream = client.GetStream())
                {
                    var        buffer        = new byte[1024];
                    NetMessage dataBuffer    = null;
                    var        bufferSize    = 0;
                    var        lengthBuffer  = new byte[2];
                    var        bytesReceived = 0;
                    int        readBytes;

                    var authMessages = new Queue <NetMessage>();
                    while (_tcpRunning)
                    {
                        readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token);

                        if (readBytes > 0)
                        {
                            var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived,
                                                                     ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue);
                            if (readMessage >= 1)
                            {
                                break;
                            }
                        }
                        if (!client.Connected)
                        {
                            return;
                        }
                    }

                    player = new Player(this)
                    {
                        TcpClient     = client,
                        NetworkStream = networkStream,
                        Status        = ConnectionStatus.Connecting
                    };
                    if (ConstructNetData != null)
                    {
                        player.NetUserData = ConstructNetData();
                    }

                    if (VerifyPlayer != null)
                    {
                        if (authMessages.Count > 0)
                        {
                            VerifyPlayer(player, authMessages.Dequeue());
                        }
                        else
                        {
                            player.Disconnect("No authentication message sent");
                        }
                    }
                    else
                    {
                        player.AllowConnect();
                    }

                    var canConnect = await player.AllowConnectCompletion.Task;
                    if (!canConnect)
                    {
                        return;
                    }

                    player.Status = ConnectionStatus.Connected;
                    FinalizePlayerAdd(player);

                    Debug.Log("Client connected from {0}", client.Client.RemoteEndPoint);
                    //and drain the rest of messages that might have come after the auth
                    while (authMessages.Count > 0)
                    {
                        player.ConsumeData(authMessages.Dequeue());
                    }

                    while (_tcpRunning)
                    {
                        readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token);

                        if (readBytes > 0)
                        {
                            NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer,
                                                   ref lengthBuffer, ref bufferSize, player.ConsumeData);
                        }
                        if (!client.Connected)
                        {
                            return;
                        }
                    }
                }
            }
            catch (OperationCanceledException o)
            {
                Debug.Log("Operation canceled");
            }
            catch (ObjectDisposedException ode)
            {
                if (_tcpRunning && ode.ObjectName != "System.Net.Sockets.NetworkStream")
                {
                    Debug.LogException(ode, "{0} disposed when it shouldn't have", ode.ObjectName);
                }
            }
            catch (SocketException se)
            {
            }
            catch (IOException ioe)
            {
                if (!(ioe.InnerException is SocketException))
                {
                    Debug.LogException(ioe);
                }
            }
            catch (Exception exp)
            {
                Debug.LogException(exp);
            }
            finally
            {
                player.Status = ConnectionStatus.Disconnecting;
                Debug.Log("Closing client connection to {0}", endpoint);
                client.Close();
                if (player != null)
                {
                    player.Status = ConnectionStatus.Disconnected;
                    RemovePlayer(player);
                    player.NetworkStream = null;
                }
            }
        }
 protected void ConsumeData(Player player, NetMessage msg)
 {
     player.ConsumeData(msg);
 }