1

我正在使用 Lidgren.Networking 在客户端/服务器架构中的服务器和客户端之间发送数据。我创建了一个 Packet 类,以便在通过网络发送数据包时使用。

数据包.cs

public abstract class Packet : IPackable
{
    public abstract void PackIntoNetMessage(NetOutgoingMessage msg);
    public abstract void PopulateFromNetMessage(NetIncomingMessage msg);
}

IPackable.cs

interface IPackable
{
    void PackIntoNetMessage(NetOutgoingMessage msg);
    void PopulateFromNetMessage(NetIncomingMessage msg);
}

然后我有这样的应用程序特定数据包类

public class PositionPacket : Packet
{
    public int PosX { get; set; }
    public int PosY { get; set; }

    public override void PackIntoNetMessage(NetOutgoingMessage m)
    {
        m.Write((byte)Networking.PacketTypes.PositionPacket);
        m.Write(PosX);
        m.Write(PosY);
    }

    public override void PopulateFromNetMessage(NetIncomingMessage m)
    {
        PosX = m.ReadInt32();
        PosY = m.ReadInt32();
    }
}

发送数据包很容易,我只需创建一个数据包和 PackIntoNetMessage(msg) 然后发送它。但是当我尝试接收数据包时,我遇到了一些烦人的结构问题。

我从读取第一个字节开始

var packetType = (Networking.PacketTypes)incomingMsg.ReadByte();

但是然后我必须为每种数据包类型进行一个切换,以便获得正确的构造函数。

switch (packetType)
{
    case Networking.PacketTypes.PositionPacket:
        incPacket = new Packets.PositionPacket();
        break;
    default:
        incPacket = null;
        break;
}
//Populate packet from net message
incPacket.PopulateFromNetMessage(incomingMsg);

这是我不喜欢的部分。我希望能够制作一个通用的数据包处理系统来处理派生自 Packet 的任何类。我想反射不是一个好主意,因为它会破坏性能。我应该如何构建它以使其更通用?

4

1 回答 1

2

需要以某种方式创建特定类的实例,以便您可以在启动时使用反射来填充字典,其中包含派生自通过其 id 存储的 Packet 的所有可用类。

然后创建一个实例将归结为:

var packetTypeId = (Networking.PacketTypes)incomingMsg.ReadByte();
var incPackage = (Package)Activator.CreateInstance(packetTypes[packetTypeId]);

如果您担心创建很多很多实例并期望垃圾收集周期会对您的应用程序的速度产生重大影响,您可以创建一个回收实例的对象池。只要将不再使用的对象放回池中,就可以防止 GC 循环。

var packetTypeId = (Networking.PacketTypes)incomingMsg.ReadByte();
Type packetType = packetTypes[packetTypeId];
Package incPackage;
if(!pool.TryGetRecycledInstance(packetType, out incPackage))
{
    incPackage = (Package)Activator.CreateInstance(packetType);
}
于 2014-08-04T09:54:27.463 回答