示例#1
0
        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);
 }