Show / Hide Table of Contents

# NetPacketProcessor

Fast specialized for network purposes serializer.
It supports classes with public properties with "get" and "set" methods or classes/structs which implements `INetSerializable`.
Serializer adds some overhead to packet size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet.

## Serialization speed comparsion

Serialization 100000 times of simple structure from example (`NET 4.5`): Serializer|Time|Size ---|---|---| BinaryFormatter|3334 ms|1096 bytes NetSerializer (first run)|45 ms|204 bytes NetSerializer (second run)|37 ms|204 bytes Raw|24 ms|204 bytes

## Supported property types

    byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint

Arrays of all these types (and custom types) are also supported.
Enums are supported but work a bit slower than other types.

## Custom types

NetPacketProcessor doesn't support nested structs or classes, but you can register your own custom type processors.
That useful for game engine types such as Vector3 and Quaternion (in Unity3d).

    // Your packet that will be sent over network
    class SamplePacket
    {
    	// Both property and array are supported
        public MyType SomeMyType { get; set; }
        public MyType[] SomeMyTypes { get; set; }
    }

    // Some custom type variant 1: Basic struct
    struct MyType
    {
        public int Value1;
        public string Value2;

        public static void Serialize(NetDataWriter writer, SomeMyType mytype)
        {
            writer.Put(mytype.Value1);
            writer.Put(mytype.Value2);
        }

        public static MyType Deserialize(NetDataReader reader)
        {
            MyType res = new MyType();
            res.Value1 = reader.GetInt();
            res.Value2 = reader.GetString();
            return res;
        }
    }
    ...
    netPacketProcessor = new NetPacketProcessor();
    netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); // Supply Serialization methods

You can also implement INetSerializable interface:

    // Some custom type variant 2: INetSerializable struct
    struct MyType : INetSerializable
    {
        public int Value1;
        public string Value2;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(Value1);
            writer.Put(Value2);
        }

        public void Deserialize(NetDataReader reader)
        {
            Value1 = reader.GetInt();
            Value2 = reader.GetString();
        }
    }
    ...
    netPacketProcessor = new NetPacketProcessor();
    netPacketProcessor.RegisterNestedType<MyType>(); // Serialization handled automatically thanks to INetSerializable

If you want to use a class instead of a struct you must implement the INetSerializable interface and provide a constructor:

    // Some custom type variant 3: Class, must implement INetSerializable
    class MyType : INetSerializable
    {
        public int Value1;
        public string Value2;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(Value1);
            writer.Put(Value2);
        }

        public void Deserialize(NetDataReader reader)
        {
            Value1 = reader.GetInt();
            Value2 = reader.GetString();
        }
    }
    ...
    netPacketProcessor = new NetPacketProcessor();
    netPacketProcessor.RegisterNestedType<MyType>(() => { return new SomeMyType(); }); // Must provide constructor

## Usage example

For full example look at source SerializerBenchmark

### Packet

    class SamplePacket
    {
    	// All of these will be automatically serialized and deserialized
        public string SomeString { get; set; }
        public float SomeFloat { get; set; }
        public int[] SomeIntArray { get; set; }
    }

### Sending / recieving

    // Client
    class SomeClientListener : INetEventListener
    {
       private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor();
    ...
       public void OnPeerConnected(NetPeer peer)
       {
    		// After connection is established you will have the server as a NetPeer
           SamplePacket packet = new SamplePacket
           {
               SomeFloat = 3.42f,
               SomeIntArray = new[] {6, 5, 4},
               SomeString = "Test String",
           }
           // Serialize the packet with NetSerializer and send it to the peer (server)
           peer.Send(_netPacketProcessor.Write(packet), DeliveryMethod.ReliableOrdered);
           //You can also use _netPacketProcessor.Send(peer, packet, DeliveryMethod.ReliableOrdered);
       }
    }

    // Server
    class SomeServerListener : INetEventListener
    {
        private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor();

        public SomeServerListener()
        {
            // Subscribe to recieving packets.
            _netPacketProcessor.SubscribeReusable<SamplePacket, NetPeer>(OnSamplePacketReceived);
        }

    	// Handler for SamplePacket, registered in constructor above
        private void OnSamplePacketReceived(SamplePacket samplePacket, NetPeer peer)
        {
            Console.WriteLine("[Server] ReceivedPacket:\n" + samplePacket.SomeString);
        }

    	// INetEventListener function.
        public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
        {
            Console.WriteLine("[Server] received data. Processing...");
            // Deserializes packet and calls the handler registered in constructor
            _netPacketProcessor.ReadAllPackets(reader, peer);
        }
    }

### Mini FAQ

Q: `NetPacketProcessor` throws "`Undefined packet in NetDataReader`" but all packets are registered.
A: This can happen when packet definitions resides in different namespaces. Check that registered packet classes/structs are in the same namespace on both ends. To avoid this error altogether, use shared code/-assembly for packets.