patterncsharpMinor
Network package management
Viewed 0 times
managementnetworkpackage
Problem
As part of a small game engine I'm currently working on, I have written a "NetLib".
NetLib should manage different types of packages through PacketStreams which are based on TcpClients.
I'm quite unsure if my implementation of
```
public class PacketStream : IDisposable
{
public bool Connected { get; private set; } = true;
public IAvailabilityStream Stream { get { return _stream; } }
private readonly PacketStreamReader _reader;
private readonly PacketStreamWriter _writer;
private readonly IAvailabilityStream _stream;
private readonly Dictionary> _readerStrategies = new Dictionary>();
private readonly Dictionary> _writerStrategies = new Dictionary>();
private readonly PacketBase _emptyPacket = new EmptyPacket();
internal PacketStream(IAvailabilityStream stream)
{
_stream = stream;
_reader = new PacketStreamReader(stream, Encoding.UTF8);
_writer = new PacketStreamWriter(stream, Encoding.UTF8);
}
public void Write(PacketBase packet)
{
if (!_writerStrategies.ContainsKey(packet.PacketTypeId))
{
throw new InvalidOperationException($"Packet with ID {packet.PacketTypeId} was not found in WriterStrategies.");
}
try
{
_writer.Write(packet.PacketTypeId);
_writerStrategiespacket.PacketTypeId;
}
catch (Exception e)
{
Connected = false;
}
}
public async Task WriteAsyc(PacketBase packet)
{
if (!_writerStrategies.ContainsKey(packet.PacketTypeId))
{
throw new InvalidOperationException($"Packet with ID {packet.PacketTypeId} was not found in WriterStrategies.");
}
await _writer.WriteAsyn
NetLib should manage different types of packages through PacketStreams which are based on TcpClients.
I'm quite unsure if my implementation of
PacketStream and related classes is reasonable or whether I'm overdoing it.```
public class PacketStream : IDisposable
{
public bool Connected { get; private set; } = true;
public IAvailabilityStream Stream { get { return _stream; } }
private readonly PacketStreamReader _reader;
private readonly PacketStreamWriter _writer;
private readonly IAvailabilityStream _stream;
private readonly Dictionary> _readerStrategies = new Dictionary>();
private readonly Dictionary> _writerStrategies = new Dictionary>();
private readonly PacketBase _emptyPacket = new EmptyPacket();
internal PacketStream(IAvailabilityStream stream)
{
_stream = stream;
_reader = new PacketStreamReader(stream, Encoding.UTF8);
_writer = new PacketStreamWriter(stream, Encoding.UTF8);
}
public void Write(PacketBase packet)
{
if (!_writerStrategies.ContainsKey(packet.PacketTypeId))
{
throw new InvalidOperationException($"Packet with ID {packet.PacketTypeId} was not found in WriterStrategies.");
}
try
{
_writer.Write(packet.PacketTypeId);
_writerStrategiespacket.PacketTypeId;
}
catch (Exception e)
{
Connected = false;
}
}
public async Task WriteAsyc(PacketBase packet)
{
if (!_writerStrategies.ContainsKey(packet.PacketTypeId))
{
throw new InvalidOperationException($"Packet with ID {packet.PacketTypeId} was not found in WriterStrategies.");
}
await _writer.WriteAsyn
Solution
This approach adds a very good first glance at what will happen during code execution. If you look at
Just a couple of tips:
Use enums when possible and cast int to enum not vice versa.
Currently:
Better:
This is more readable as the cast to int does not confuse during packet registration.
If you want PacketStream to be reusable, you could introduce a type parameter for the package key.
Check your
See: MSDN - Disposable pattern
Naming Conventions:
Your enum member name are all uppercase and separated by underscores. This is not a common pattern in C#. (Of course this always depends on taste)
See: MSDN - Framework Design Guidelines
PacketStreamFactoryyou can already see all the packets that the program is able to process. Just a couple of tips:
Use enums when possible and cast int to enum not vice versa.
Currently:
Dictionary _readerStrategies;
_readerStrategies.Add((int)PacketType.HEARTBEAT, new object());
_readerStrategies[packet.PacketTypeId];Better:
Dictionary _readerStrategies;
_readerStrategies.Add(PacketType.HEARTBEAT, new object());
_readerStrategies[(PacketType)packet.PacketTypeId];This is more readable as the cast to int does not confuse during packet registration.
If you want PacketStream to be reusable, you could introduce a type parameter for the package key.
PacketStream and PacketBaseCheck your
IDisposable implementationIDisposable is not as simple as it looks.See: MSDN - Disposable pattern
Naming Conventions:
Your enum member name are all uppercase and separated by underscores. This is not a common pattern in C#. (Of course this always depends on taste)
See: MSDN - Framework Design Guidelines
Code Snippets
Dictionary<int, object> _readerStrategies;
_readerStrategies.Add((int)PacketType.HEARTBEAT, new object());
_readerStrategies[packet.PacketTypeId];Dictionary<PacketType, object> _readerStrategies;
_readerStrategies.Add(PacketType.HEARTBEAT, new object());
_readerStrategies[(PacketType)packet.PacketTypeId];Context
StackExchange Code Review Q#162907, answer score: 2
Revisions (0)
No revisions yet.