/// <summary> /// Poll the socket for waiting data and parse. /// </summary> private void ReceiveMessages() { if (this.socket.Poll(POLL_TIMEOUT, SelectMode.SelectRead)) { // Read waiting raw bytes. int received = this.socket.Receive(this.packetBuffer, BUFFER_SIZE, SocketFlags.None); if (received > 0) { int offset = 0; while (offset < received) { // While we have data to read, attempt to parse the bytes into a packet. IPacket packet; int processed = Framing.ReadPacket(this.packetBuffer, received - offset, offset, out packet); if (packet != null) { // Generic message packet (enqueue in our local message broker if (packet.PacketHeader == Framing.HDR_PACKET) { Packet msgPacket = (Packet)packet; Debug.Log(String.Format("[ServerConnection.ReceiveMessages] Got message packet containing {0} messages at timestamp {1:g}", msgPacket.Count, DateTime.FromBinary(msgPacket.Timestamp))); foreach (Msg msg in msgPacket) { // Sanity check in case server messages somehow get sent to client if (msg.IsClient()) { MessageBroker.Instance.Enqueue(msg); } } } // Monster packet (tell the spawn manager to create/update new monster instance) else if (packet.PacketHeader == Framing.HDR_MONSTER) { MonsterPacket monPacket = (MonsterPacket)packet; Debug.Log(String.Format("[ServerConnection.ReceiveMessages] Got monster packet containing monster instance {0}", monPacket.MonsterInstance.ObjectID)); SpawnManager.Instance.QueueMonsterUpdate(monPacket.MonsterInstance); } } offset += processed; } } else { Debug.LogWarning("[ServerConnection.ReceiveMessages] No data received. Connection lost?"); } } }
/// <summary> /// Processes messages on the connected client socket. Blocks until the socket is closed. /// </summary> public void Process() { // Subscribe to the client message queue MessageBroker.Clients.Subscribe(this); while (true) { try { // 1. Check for data to be read if (this.socket.Poll(POLL_WAIT, SelectMode.SelectRead)) { int received = this.socket.Receive(readBuffer, BUFFER_SIZE, SocketFlags.None); if (received > 0) { int offset = 0; while (offset < received) { // If we have data, attempt to parse it into a packet IPacket packet; int processed = Framing.ReadPacket(readBuffer, received - offset, offset, out packet); if (packet != null) { switch (packet.PacketHeader) { case Framing.HDR_PACKET: Debug.WriteLine("Got a message packet with " + ((Packet)packet).Count + " messages"); HandleMessagePacket((Packet)packet); break; case Framing.HDR_MONSTER: Debug.WriteLine("[ConnectedClient.Process] Client shouldn't be sending Monster packets"); break; default: Debug.WriteLine("[ConnectedClient.Process] Unhandled packet type: " + packet.PacketHeader); break; } } offset += processed; } } else { // client disconnected break; } // if (received > 0... } // if (this.socket.Poll... } catch (SocketException ex) { Debug.WriteLine("[ConnectedClient.Process] Socket error: " + ex.Message + " " + ex.NativeErrorCode); break; } // 2. Gather up any messages to be sent QueueMessagesToPacket(); // 3. Send data to be written if (!SendQueuedPackets()) { // client disconnected break; } } // while (true... // Unsubscribe from the client message queue when we're done MessageBroker.Clients.Unsubscribe(this); }