private async void HandleRoomConnection(TcpClient client) { var endpoint = client.Client.RemoteEndPoint; Debug.Log("Room connection request from {0}", endpoint); client.ReceiveBufferSize = 1024; client.SendBufferSize = 1024; client.NoDelay = true; client.LingerState = new LingerOption(true, 10); Room room = 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; } } string denyReason; if ( !ApproveRoomConnection((IPEndPoint)client.Client.RemoteEndPoint, authMessages.Count > 0 ? authMessages.Dequeue() : null, out denyReason, out room)) { var dcMessage = GetMessage(denyReason.Length * 2 + 1); dcMessage.Write(false); dcMessage.WritePadBits(); dcMessage.Write(denyReason); dcMessage.WriteSize(); await networkStream.WriteAsync(dcMessage.Data, 0, dcMessage.LengthBytes, _shutdownTokenSource.Token); return; } else { var cMessage = GetMessage(17); cMessage.Write(true); cMessage.WritePadBits(); cMessage.Write(room.Guid); cMessage.WriteSize(); await networkStream.WriteAsync(cMessage.Data, 0, cMessage.LengthBytes, _shutdownTokenSource.Token); } room.TcpClient = client; room.NetworkStream = networkStream; AddRoom(room); UpdateRoomsOfNewRoom(room); Debug.LogWarning("Room {1} connected from {0}, connectable at {2}", client.Client.RemoteEndPoint, room.RoomId, room.Address); while (authMessages.Count > 0) { room.ConsumeData(authMessages.Dequeue()); } while (_tcpRunning && room.Running) { 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, room.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 { Debug.Log("Closing room connection to {0}", endpoint); client.Close(); if (room != null) { RemoveRoom(room); room.NetworkStream = null; //todo: move all players in the room to a new room. } } }
protected void ConsumeData(Room room, NetMessage msg) { room.ConsumeData(msg); }