Sistema de paquetes de jugador -- # campo con multithreading campo con socket camp codereview Relacionados El problema

Player Packet System


1
vote

problema

Español

He codificado recientemente un sistema donde se crea una instancia de reproductor de clase para cada socket conectado, una vez que se ha creado la clase de jugador, en su constructor, el zócalo que conectó comienza a recibir datos del lado del cliente.

No incluiré el código del lado del cliente, solo el lado del servidor para esta pregunta. Una vez que el socket ha comenzado a recibir, comenzó a recibir bits de datos, cada mensaje contiene un ID de paquete único que luego descubre el identificador de paquetes con algún código, lo que he publicado a continuación.

¿Qué estoy preguntando?
¿Cómo puedo mejorar este código de alguna manera, alguna sugerencia?

Player.cs:

  namespace Hariak_Emulator.Emulator.Base.Game.Habbo.Players.Players {     using System;     using System.Net.Sockets;     using System.Text;     using NLog;      internal sealed class Player : IDisposable     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Socket _socket;         private readonly PlayerPacketHandler _packetHandler;         private readonly byte[] _buffer;          internal Player(Socket socket)         {             _socket = socket;             _packetHandler = new PlayerPacketHandler(this);             _buffer = new byte[8000];              StartReceive();         }          private void StartReceive()         {             try             {                 _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);             }             catch (SocketException)             {                 Dispose();             }         }          private void OnDataReceived(IAsyncResult iAsyncResult)         {             try             {                 var bytesReceived = _socket.EndReceive(iAsyncResult);                  if (bytesReceived == 0)                 {                     Dispose();                     return;                 }                  var packet = new byte[bytesReceived];                 Array.Copy(_buffer, packet, bytesReceived);                 _packetHandler.ProcessPacketData(packet);             }             catch             {                 Dispose();             }             finally             {                 try                 {                     _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);                 }                 catch                 {                     Dispose();                 }             }         }          public void SendString(string data)         {             SendData(Encoding.UTF8.GetBytes(data));         }          private void SendData(byte[] data)         {             try             {                 _socket.BeginSend(data, 0, data.Length, 0, OnSend, null);             }             catch (SocketException socketException)             {                 Logger.Error("Error sending message to socket: " + socketException.Message);                 Logger.Error(socketException);                 Dispose();             }         }          private void OnSend(IAsyncResult asyncResult)         {             try             {                 if (_socket == null)                 {                     return;                 }                  _socket.EndSend(asyncResult);             }             catch (SocketException)             {                 Dispose();             }         }          public void Dispose()         {             Dispose(true);         }          private void Dispose(bool disposing)         {             if (!disposing)             {                 return;             }              //todo: properly dispose         }     } }   

PlayerPacketHandler.cs:

  namespace Hariak_Emulator.Emulator.Base.Game.Habbo.Players.Players {     using System;     using System.IO;     using System.Net.Sockets;     using System.Text;     using NLog;     using Utilities;      internal sealed class PlayerPacketHandler     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Player _player;         private readonly byte[] _buffer;          private byte[] _dataReceived;         private bool _halfDataRecieved;         private bool _decryptedData;          internal PlayerPacketHandler(Player player)         {             _player = player;             _buffer = new byte[8000];         }          internal void ProcessPacketData(byte[] receivedData)         {             var receivedDataStr = Encoding.Default.GetString(receivedData);             var receivedDataPacketId = receivedData[0];              if (receivedDataPacketId == 67)             {                 return;             }              if (receivedDataPacketId == 60)             {                 const string crossDomainPolicy = "<?xml version="1.0"?>  "                     +                     "<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">  "                     + "<cross-domain-policy>  "                     +                     "<site-control permitted-cross-domain-policies="master-only"/>  "                     + "<allow-access-from domain="*" to-ports="*" />  "                     + "</cross-domain-policy>x0";                  _player.SendString(crossDomainPolicy);             }             else             {                 using (var reader = new BinaryReader(new MemoryStream(receivedData)))                 {                     if (receivedData.Length < 4)                     {                         return;                     }                      var packetLength = PacketUtilities.DecodeInt32(reader.ReadBytes(4));                      if (reader.BaseStream.Length - 4 < packetLength)                     {                         _dataReceived = receivedData;                         _halfDataRecieved = true;                         return;                     }                      if (packetLength < 0 || packetLength > 5120)                     {                         return;                     }                      var packetBytes = reader.ReadBytes(packetLength);                      using (var binaryReader = new BinaryReader(new MemoryStream(packetBytes)))                     {                         var packetHeader = PacketUtilities.DecodeInt16(binaryReader.ReadBytes(2));                         var packetBodyBytes = new byte[packetBytes.Length - 2];                          Buffer.BlockCopy(packetBytes, 2, packetBodyBytes, 0, packetBytes.Length - 2);                         Hariak.HariakServer.GameManager.PacketManager.ProcessPacket(_player, packetHeader);                          _decryptedData = false;                     }                      if (reader.BaseStream.Length - 4 <= packetLength)                     {                         return;                     }                      var extra = new byte[reader.BaseStream.Length - reader.BaseStream.Position];                     Buffer.BlockCopy(receivedData, (int)reader.BaseStream.Position, extra, 0, (int)(reader.BaseStream.Length - reader.BaseStream.Position));                      _decryptedData = true;                     ProcessPacketData(extra);                 }             }         }     } }   

hariak.hariakserver.gamemanager.packetmanager:

  namespace Hariak_Emulator.Emulator.Core.Habbo.Packets {     using System;     using System.Collections.Generic;     using Base.Game.Habbo.Players.Players;     using Events;     using NLog;      internal class PacketManager     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Dictionary<int, KeyValuePair<string, IPacketEvent>> _packets;          public PacketManager()         {             _packets = new Dictionary<int, KeyValuePair<string, IPacketEvent>>();         }          public void LoadPackets()         {             // For this example I only added 1 packet, there will be over 100 on the actual code.             _packets.Add(1, new KeyValuePair<string, IPacketEvent>("MyPacketEventsNameHere", new MyPacketEvent()));         }          public void ProcessPacket(Player player, int packetId)         {             KeyValuePair<string, IPacketEvent> packet;              if (_packets.TryGetValue(packetId, out packet))             {                 Logger.Debug("Player has handled packet '" + packet.Key + "' => " + packetId + "");                 packet.Value.ProcessPacket(player);             }             else             {                 Logger.Warn("Missing packet => " + packetId + "");             }         }     } }   

iPackEVENT:

  +----------------------+----------+------------+ |                      | Failure  |   Speed    | +----------------------+----------+------------+ | 2015-01-01 00:00:00  |       0  | 0.000000   | | 2015-01-01 01:00:00  |       0  | 63.094019  | | 2015-01-01 02:00:00  |       1  | 90.006264  | | 2015-01-01 03:00:00  |       0  | 42.412872  | | 2015-01-01 04:00:00  |       0  | 0.000000   | | 2015-01-01 05:00:00  |       0  | 0.000000   | | 2015-01-01 06:00:00  |       0  | 81.793235  | | 2015-01-01 07:00:00  |       0  | 56.533471  | | 2015-01-01 08:00:00  |       0  | 152.326947 | | 2015-01-01 09:00:00  |       0  | 238.293261 | | 2015-01-01 10:00:00  |       1  | 1.220514   | | 2015-01-01 11:00:00  |       1  | 17.038855  | | 2015-01-01 12:00:00  |       1  | 13.485625  | | 2015-01-01 13:00:00  |       0  | 69.488021  | | 2015-01-01 14:00:00  |       0  | 0.000000   | | 2015-01-01 15:00:00  |       0  | 84.858909  | | 2015-01-01 16:00:00  |       0  | 20.160277  | | 2015-01-01 17:00:00  |       0  | 0.000000   | | 2015-01-01 18:00:00  |       0  | 0.000000   | | 2015-01-01 19:00:00  |       0  | 90.718714  | | 2015-01-01 20:00:00  |       0  | 164.629853 | | 2015-01-01 21:00:00  |       0  | 0.000000   | | 2015-01-01 22:00:00  |       1  | 82.629209  | | 2015-01-01 23:00:00  |       1  | 24.913644  | +----------------------+----------+------------+ 0  

mypacketevent.cs:

  +----------------------+----------+------------+ |                      | Failure  |   Speed    | +----------------------+----------+------------+ | 2015-01-01 00:00:00  |       0  | 0.000000   | | 2015-01-01 01:00:00  |       0  | 63.094019  | | 2015-01-01 02:00:00  |       1  | 90.006264  | | 2015-01-01 03:00:00  |       0  | 42.412872  | | 2015-01-01 04:00:00  |       0  | 0.000000   | | 2015-01-01 05:00:00  |       0  | 0.000000   | | 2015-01-01 06:00:00  |       0  | 81.793235  | | 2015-01-01 07:00:00  |       0  | 56.533471  | | 2015-01-01 08:00:00  |       0  | 152.326947 | | 2015-01-01 09:00:00  |       0  | 238.293261 | | 2015-01-01 10:00:00  |       1  | 1.220514   | | 2015-01-01 11:00:00  |       1  | 17.038855  | | 2015-01-01 12:00:00  |       1  | 13.485625  | | 2015-01-01 13:00:00  |       0  | 69.488021  | | 2015-01-01 14:00:00  |       0  | 0.000000   | | 2015-01-01 15:00:00  |       0  | 84.858909  | | 2015-01-01 16:00:00  |       0  | 20.160277  | | 2015-01-01 17:00:00  |       0  | 0.000000   | | 2015-01-01 18:00:00  |       0  | 0.000000   | | 2015-01-01 19:00:00  |       0  | 90.718714  | | 2015-01-01 20:00:00  |       0  | 164.629853 | | 2015-01-01 21:00:00  |       0  | 0.000000   | | 2015-01-01 22:00:00  |       1  | 82.629209  | | 2015-01-01 23:00:00  |       1  | 24.913644  | +----------------------+----------+------------+ 1  

Paquetes:

  +----------------------+----------+------------+ |                      | Failure  |   Speed    | +----------------------+----------+------------+ | 2015-01-01 00:00:00  |       0  | 0.000000   | | 2015-01-01 01:00:00  |       0  | 63.094019  | | 2015-01-01 02:00:00  |       1  | 90.006264  | | 2015-01-01 03:00:00  |       0  | 42.412872  | | 2015-01-01 04:00:00  |       0  | 0.000000   | | 2015-01-01 05:00:00  |       0  | 0.000000   | | 2015-01-01 06:00:00  |       0  | 81.793235  | | 2015-01-01 07:00:00  |       0  | 56.533471  | | 2015-01-01 08:00:00  |       0  | 152.326947 | | 2015-01-01 09:00:00  |       0  | 238.293261 | | 2015-01-01 10:00:00  |       1  | 1.220514   | | 2015-01-01 11:00:00  |       1  | 17.038855  | | 2015-01-01 12:00:00  |       1  | 13.485625  | | 2015-01-01 13:00:00  |       0  | 69.488021  | | 2015-01-01 14:00:00  |       0  | 0.000000   | | 2015-01-01 15:00:00  |       0  | 84.858909  | | 2015-01-01 16:00:00  |       0  | 20.160277  | | 2015-01-01 17:00:00  |       0  | 0.000000   | | 2015-01-01 18:00:00  |       0  | 0.000000   | | 2015-01-01 19:00:00  |       0  | 90.718714  | | 2015-01-01 20:00:00  |       0  | 164.629853 | | 2015-01-01 21:00:00  |       0  | 0.000000   | | 2015-01-01 22:00:00  |       1  | 82.629209  | | 2015-01-01 23:00:00  |       1  | 24.913644  | +----------------------+----------+------------+ 2  
Original en ingles

I have recently coded a system where an instance of class Player is created for each connected socket, once the player class has been created, in its constructor the Socket that connected starts receiving data from the client side.

I won't be including the client side code, just the server side for this question. Once the socket has started receiving, it started receiving bits of data, each message contains a unique packet id which then it finds out the packet identifier with some code, which I have posted below.

What am I asking?
How can I improve this code in any way, any suggestions?

Player.cs:

namespace Hariak_Emulator.Emulator.Base.Game.Habbo.Players.Players {     using System;     using System.Net.Sockets;     using System.Text;     using NLog;      internal sealed class Player : IDisposable     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Socket _socket;         private readonly PlayerPacketHandler _packetHandler;         private readonly byte[] _buffer;          internal Player(Socket socket)         {             _socket = socket;             _packetHandler = new PlayerPacketHandler(this);             _buffer = new byte[8000];              StartReceive();         }          private void StartReceive()         {             try             {                 _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);             }             catch (SocketException)             {                 Dispose();             }         }          private void OnDataReceived(IAsyncResult iAsyncResult)         {             try             {                 var bytesReceived = _socket.EndReceive(iAsyncResult);                  if (bytesReceived == 0)                 {                     Dispose();                     return;                 }                  var packet = new byte[bytesReceived];                 Array.Copy(_buffer, packet, bytesReceived);                 _packetHandler.ProcessPacketData(packet);             }             catch             {                 Dispose();             }             finally             {                 try                 {                     _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);                 }                 catch                 {                     Dispose();                 }             }         }          public void SendString(string data)         {             SendData(Encoding.UTF8.GetBytes(data));         }          private void SendData(byte[] data)         {             try             {                 _socket.BeginSend(data, 0, data.Length, 0, OnSend, null);             }             catch (SocketException socketException)             {                 Logger.Error("Error sending message to socket: " + socketException.Message);                 Logger.Error(socketException);                 Dispose();             }         }          private void OnSend(IAsyncResult asyncResult)         {             try             {                 if (_socket == null)                 {                     return;                 }                  _socket.EndSend(asyncResult);             }             catch (SocketException)             {                 Dispose();             }         }          public void Dispose()         {             Dispose(true);         }          private void Dispose(bool disposing)         {             if (!disposing)             {                 return;             }              //todo: properly dispose         }     } } 

PlayerPacketHandler.cs:

namespace Hariak_Emulator.Emulator.Base.Game.Habbo.Players.Players {     using System;     using System.IO;     using System.Net.Sockets;     using System.Text;     using NLog;     using Utilities;      internal sealed class PlayerPacketHandler     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Player _player;         private readonly byte[] _buffer;          private byte[] _dataReceived;         private bool _halfDataRecieved;         private bool _decryptedData;          internal PlayerPacketHandler(Player player)         {             _player = player;             _buffer = new byte[8000];         }          internal void ProcessPacketData(byte[] receivedData)         {             var receivedDataStr = Encoding.Default.GetString(receivedData);             var receivedDataPacketId = receivedData[0];              if (receivedDataPacketId == 67)             {                 return;             }              if (receivedDataPacketId == 60)             {                 const string crossDomainPolicy = "<?xml version=\"1.0\"?>\r\n"                     +                     "<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\r\n"                     + "<cross-domain-policy>\r\n"                     +                     "<site-control permitted-cross-domain-policies=\"master-only\"/>\r\n"                     + "<allow-access-from domain=\"*\" to-ports=\"*\" />\r\n"                     + "</cross-domain-policy>\x0";                  _player.SendString(crossDomainPolicy);             }             else             {                 using (var reader = new BinaryReader(new MemoryStream(receivedData)))                 {                     if (receivedData.Length < 4)                     {                         return;                     }                      var packetLength = PacketUtilities.DecodeInt32(reader.ReadBytes(4));                      if (reader.BaseStream.Length - 4 < packetLength)                     {                         _dataReceived = receivedData;                         _halfDataRecieved = true;                         return;                     }                      if (packetLength < 0 || packetLength > 5120)                     {                         return;                     }                      var packetBytes = reader.ReadBytes(packetLength);                      using (var binaryReader = new BinaryReader(new MemoryStream(packetBytes)))                     {                         var packetHeader = PacketUtilities.DecodeInt16(binaryReader.ReadBytes(2));                         var packetBodyBytes = new byte[packetBytes.Length - 2];                          Buffer.BlockCopy(packetBytes, 2, packetBodyBytes, 0, packetBytes.Length - 2);                         Hariak.HariakServer.GameManager.PacketManager.ProcessPacket(_player, packetHeader);                          _decryptedData = false;                     }                      if (reader.BaseStream.Length - 4 <= packetLength)                     {                         return;                     }                      var extra = new byte[reader.BaseStream.Length - reader.BaseStream.Position];                     Buffer.BlockCopy(receivedData, (int)reader.BaseStream.Position, extra, 0, (int)(reader.BaseStream.Length - reader.BaseStream.Position));                      _decryptedData = true;                     ProcessPacketData(extra);                 }             }         }     } } 

Hariak.HariakServer.GameManager.PacketManager:

namespace Hariak_Emulator.Emulator.Core.Habbo.Packets {     using System;     using System.Collections.Generic;     using Base.Game.Habbo.Players.Players;     using Events;     using NLog;      internal class PacketManager     {         private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();          private readonly Dictionary<int, KeyValuePair<string, IPacketEvent>> _packets;          public PacketManager()         {             _packets = new Dictionary<int, KeyValuePair<string, IPacketEvent>>();         }          public void LoadPackets()         {             // For this example I only added 1 packet, there will be over 100 on the actual code.             _packets.Add(1, new KeyValuePair<string, IPacketEvent>("MyPacketEventsNameHere", new MyPacketEvent()));         }          public void ProcessPacket(Player player, int packetId)         {             KeyValuePair<string, IPacketEvent> packet;              if (_packets.TryGetValue(packetId, out packet))             {                 Logger.Debug("Player has handled packet '" + packet.Key + "' => " + packetId + "");                 packet.Value.ProcessPacket(player);             }             else             {                 Logger.Warn("Missing packet => " + packetId + "");             }         }     } } 

IPacketEvent:

namespace Hariak_Emulator.Emulator.Core.Habbo.Packets {     internal interface IPacketEvent     {         void ProcessPacket(Player player);     } } 

MyPacketEvent.cs:

namespace Hariak_Emulator.Emulator.Core.Habbo.Packets.Events {     internal class MyPacketEvent: IPacketEvent     {         public void ProcessPacket(Player player)         {             // process packet here?         }     } } 

PacketUtilities:

namespace Hariak_Emulator.Emulator.Utilities {     internal static class PacketUtilities     {         internal static int DecodeInt32(byte[] bytes)         {             if ((bytes[0] | bytes[1] | bytes[2] | bytes[3]) < 0)             {                 return -1;             }              return (bytes[0] << 0x18) + (bytes[1] << 0x10) + (bytes[2] << 8) + bytes[3];         }          internal static int DecodeInt16(byte[] bytes)         {             if ((bytes[0] | bytes[1]) < 0)             {                 return -1;             }             return (bytes[0] << 8) + bytes[1];         }     } } 
        
         
         

Lista de respuestas

5
 
vote
  1. Usted tiene demasiados Dispose Llamadas en 9988777665544331 clase, la mitad de los cuales huele. Esto, por ejemplo:

              catch         {             Dispose();         }         finally         {             try             {                 _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);             }             catch             {                 Dispose();             }         }   

    Prácticas garantías, que trabajará con el estado desechado de su objeto en su bloqueo finally si atrapa una excepción antes. Dispose debe ser llamado por código externo cuando se realiza usando su objeto. No por objeto en sí, cuando usted asuma ya no es necesario. Además, su método Dispose5544335 está incompleto, tanto en términos de la siguiente disposición del patrón como en términos de implementación real, lo que plantea todo tipo de banderas rojas. Si no sabe cómo implementar adecuadamente el método de disposición, no lo implemente en absoluto hasta que lo haga. Si lo sabe, entonces hágalo antes de pedir una revisión.

  2. "El jugador" no es el mejor nombre para describir lo que hace la clase. Creo que Connection (o 9988776655544337 ) es mejor.

  3. Las API basadas en devolución de llamada son algo obsoletas. Si está utilizando la versión moderna de C #, es posible que desee usar API basada en ASYCN. Busque socket .____ Métodos ASYNC en MSDN

  4. new PlayerPacketHandler(this) es el tipo de acoplamiento ajustado que es posible que desee evitar. No sé cuál es la mejor manera de refactar su código, ya que no tengo contexto, pero la forma más directa es agregar el valor de retorno a ProcessPacketData Método:

      Player0  

    De esta manera Player1 Ya no necesita una referencia a Player2 y se puede usar y, lo que es más importante, probado por unidades por separado de él.

  5. Como puede ver Player3 ya es bastante grande, y solo tiene 3 tipos de paquetes hasta ahora. Si está más en camino, debe considerar abstraer la lógica de análisis en componentes separados (en un analizador por ejemplo, por ejemplo).

  6. El tamaño de tampón
  7. probablemente no debería ser codificado en varios lugares. En su lugar, debe provenir de la configuración de las clases, por lo que es fácil ajustar si es necesario.
  8. dependencias estáticas son malvadas . Primer par de veces miré a través de su código. Me perdí completamente Player4 Referencia estática oculta en lo profundo de su código. Y así, cualquier otra persona leyenda. Si necesita una dependencia, inyecte en constructor, no acceda al azar en cualquier lugar que desee. Esto ayuda a que su código sea más legible, más probable y menos propenso a errores.
  9. En general, creo que la mejora principal que puede hacer es hacer que su lógica de procesamiento esté plana. Su Player5 Llamadas "Handler", que llama "Manager", que llama Player6 de nuevo, etc. Este CallStack es demasiado profundo y demasiado complejo. En su lugar, sentárselo en un solo lugar, por lo que todo el proceso es fácil de entender. Aquí hay algunos pseudo-código:

      Player7  

    El punto del ejemplo anterior es que 99887776655443318 no llama Player9 y no tengo conocimiento de ello. Lo mismo ocurre con la relación entre catch { Dispose(); } finally { try { _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket); } catch { Dispose(); } } 0 y catch { Dispose(); } finally { try { _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket); } catch { Dispose(); } } 1 . Este es el tipo de acoplamiento suelto que debe intentar lograr.

 
  1. You have way too many Dispose calls in Player class, half of which smell. This for example:

            catch         {             Dispose();         }         finally         {             try             {                 _socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnDataReceived, _socket);             }             catch             {                 Dispose();             }         } 

    pretty much guarantees, that you will work with disposed state of your object in your finally block if you catch an exception earlier. Dispose should be called by external code when it is done using your object. Not by object itself when you assume it is no longer needed. Also, your Dispose method is incomplete, both in terms of following dispose pattern and in terms of actual implementation, which raises all sorts of red flags. If you don't know how to properly implement dispose method - don't implement it at all until you do. If you do know - then do so before asking for review.

  2. "Player" is not the best name to describe what the class does. I think Connection (or PlayerConnection) is better.

  3. Callback-based APIs are somewhat obsolete. If you are using modern version of C# you might want to use asycn-based API instead. Look up Socket.____Async methods on MSDN

  4. new PlayerPacketHandler(this) is the kind of tight coupling you might want to avoid. I do not know what is the best way to refactor your code, since I have no context, but the most straightforward way is to add return value to ProcessPacketData method:

    var packet = new byte[bytesReceived]; Array.Copy(_buffer, packet, bytesReceived);  byte[] response = _packetHandler.ProcessPacketData(packet); if (response != null) {     Send(response); } 

    this way PlayerPacketHandler no longer needs a reference to Player and can be used and, more importantly, unit-tested separately from it.

  5. As you can see ProcessPacketData method is already pretty large, and you only have 3 types of packets so far. If more is on the way, then you should consider abstracting parsing logic into separate components (on one parser per packet type basis, for example).

  6. Buffer size probably shouldn't be hard-coded in multiple places. Instead it should come from configuration of sorts, so it is easy to tweak if needed.
  7. Static dependencies are evil. First couple of times I looked through your code I completely missed Hariak.HariakServer.GameManager.PacketManager static reference hidden deep inside your code. And so will any other person reading it. If you need a dependency - inject it in constructor, don't randomly access it anyplace you want. This helps to make your code more readable, more testable and less error-prone.
  8. Overall, I think the main improvement you can make is to make your processing logic flat. Your Player calls "handler", which calls "manager", which calls Player again, etc. This callstack is too deep and too complex. Instead lay it out in one place, so the whole process is easy to understand. Here is some pseudo-code:

    //get raw packet from network byte[] data = await _connection.Receive(); //parse raw buffer into strongly typed object IPacket packet = _parser.Parse(data); //process the data IPacket response = _processor.ProcessData(packet); if (response != null) {     //send response if any     _connection.Send(response.ToArray()); } 

    The point of above example is that _parser does not call _processor and have no knowledge of it. Same goes for relation between _processor and _connection. This is the kind of loose coupling you should try to achieve.

 
 

Relacionados problema

4  C Socket Parte-1  ( C socket part 1 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. Fuente completa: https://github.com/...

10  Protocolo de red usando TCP, enviando imágenes a través de sockets  ( Network protocol using tcp sending images through sockets ) 
Me gustaría preguntar sobre su opinión sobre mi código. La idea es simple: diseñé mi propio protocolo, donde el cliente le pregunta al servidor sobre la image...

8  Sockets y redes para un juego multiplataforma  ( Sockets and networking for a multi platform game ) 
Estoy en el proceso de agregar soporte de red para un poco de MAC & AMP; Game Windows que estoy escribiendo. Hoy he terminado de los sockets básicos más algun...

1  Recibir todos los datos viene de la web en System.NET.Socket  ( Receiving all data comes from web in system net socket ) 
Escucho en un puerto a través del zócalo Multi Hilo Async. Ese puerto recibe solicitudes sobre XDomainRequest. Recibí los datos completos cada vez hasta ahora...

1  Nede.js juego Uso de CPU  ( Node js game cpu usage ) 
Mi amigo y yo estamos haciendo un juego de nodos.js, y hemos estado probando la CPU. Después de perfilar, se determinó que este proceso llamado Zlib está succ...

5  C ++ Socket Part-3  ( C socket part 3 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. Fuente completa: https://github.com/...

0  C ++ Socket Part-4  ( C socket part 4 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. Fuente completa: https://github.com/...

5  Clase de socket para uso en servidor web  ( Socket class for use in web server ) 
He creado esta clase de socket para usar en mi aplicación Web Server. Tengo dos clases: una para el zócalo y el otro para el servidor web. import 'package:...

5  C ++ Socket Part-2  ( C socket part 2 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. fuente completa . primer artículo ...

6  Implementación del protocolo, TCP, envío de imágenes a través de sockets - Seguimiento  ( Protocol implementation tcp sending images through sockets follow up ) 
Me gustaría preguntar sobre su opinión sobre mi código. La idea es simple: diseñé mi propio protocolo, donde el cliente le pregunta al servidor sobre la image...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos