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); }