How to properly read and deserialize a MessagePackC-Sharp message?

Hello all,
I am using MessagePack to serialize my message and sending it over to my sever but am having trouble figuring out how to get the data out properly.

I am sending it in this manner currently to test :

            var msg = NOC.Serialize(opCode, opReqCode, parameters);
            con.SendByChannel(MsgType.InternalHighest+1, new ByteArray() { Data = msg }, channel);

Where ByteArray simply is a class derived from MessageBase including “public byte[ ] Data { get; set; }”

On the receiving end I am attempting to use this :

      private void RegisterHandlers()
        {
            NetworkServer.RegisterHandler(MsgType.InternalHighest+1, IncomingOperationHandler);
        }

        private void IncomingOperationHandler(NetworkMessage msg)
        {
            msg.reader.SeekZero();
            var deserial = NOC.Deserialize(msg.reader.ReadBytesAndSize());
            Debug.Log(deserial);
        }

I was trying to use the reader.SeekZero(); because I was getting an error of “IndexOutOfRangeException: NetworkReader:ReadByte out of range:NetBuf sz:0 pos:0” and a thread I saw suggested it so I gave it a try but it didnt help.

The Deserialize method includes :

        public static object[] Deserialize(byte[] deserial)
        {
            var deserializedmsg = LZ4MessagePackSerializer.Deserialize<object[]>(deserial);
            Debug.Log("Msg Deserialized");
            return deserializedmsg;
        }

I am pretty sure I am just missing something in the IncomingOperationHandler, I am not quite sure how I should be actually handling the message, any ideas?

Thanks!


Edit : Looks like using this got me closer.

  var msg1 = msg.ReadMessage<ByteArray>().Data;
var deserial = NOC.Deserialize(msg1);

But now I am getting this.

    [Exception] NullReferenceException: Object reference not set to an instance of an object
    LZ4MessagePackSerializer.Deserialize[T]()    Assets/Scripts/MessagePack/LZ4/LZ4MessagePackSerializer.cs:141
    139:   public static T Deserialize<T>(byte[] bytes, IFormatterResolver resolver)
    140:   {
    -->141:       return DeserializeCore<T>(new ArraySegment<byte>(bytes, 0, bytes.Length), resolver);
    142:   }
 
    LZ4MessagePackSerializer.Deserialize[T]()    Assets/Scripts/MessagePack/LZ4/LZ4MessagePackSerializer.cs:136
    134:   public static T Deserialize<T>(byte[] bytes)
    135:   {
    -->136:       return Deserialize<T>(bytes, null);
    137:   }
 
    NOC.Deserialize()    Assets/_Components/_Server/_Server/NOC.cs:90
    88:   public static object[] Deserialize(byte[] deserial)
    89:   {
    -->90:       var deserializedmsg = LZ4MessagePackSerializer.Deserialize<object[]>(deserial);
    91:       Debug.Log("Msg Deserialized");
    92:       return deserializedmsg;
 
    WorldEngine.IncomingOperationHandler()    Assets/_Components/_Server/_Server/WorldEngine.cs:107
    105:   {
    106:       var msg1 = msg.ReadMessage<ByteArray>();
    -->107:       var deserial = NOC.Deserialize(msg1.Data);
    108:       Debug.Log(deserial);
    109:   }

I got it figured out.

I have a similar error and I’m looking for a solution.
What helped you?

Depends, lol. What is your current error? I went through like 10 different ones while getting it working.

simple class
I use it to send data to the server and they successfully reach

public class MXPacketFormat : MessageBase
{
    public byte[] bytes;
    public short TypePkg = -1;

    public override void Deserialize(NetworkReader reader)
    {
      bytes = reader.ReadBytesAndSize();
    }

    public override void Serialize(NetworkWriter writer)
    {
        writer.WriteBytesFull(bytes);
    }
}

I send the data to the server in this way

private void TransmitToServer(MXPacketFormat data)
{
   base.connectionToServer.Send(data.TypePkg, data);
}

Client is so

private void TransmitToClients(MXPacketFormat data)
{
     base.connectionToClient.Send(data.TypePkg, data);
}

But
Deserialize(NetworkReader reader)
always reader.Length = 0 bytes.

I would take your serialization stuff out of the MessageBase class, that is what is used to encapsulate your data, for lack of a better explanation. I only have what is needed in there and I do the serialization to that class more or less, not within it. At least, that works for me, lol. I am not sure if things are different with MXPacket though.

I have my class in which I will serialize here:

        [MessagePackObject]
        public class OperationRequest : MessageBase
        {
            [Key(0)]
            public byte opCode { get; set; }

            [Key(1)]
            public byte opReqCode { get; set; }

            [Key(2)]
            public Dictionary<byte, object> parameters { get; set; }
        }

Which I then call the class and serialize it.

 var msg = new EventRequestMsg { opCode = opCodetemp, eventCode = eventCodetemp, parameters = parameterstemp };
            var serializedmsg = LZ4MessagePackSerializer.Serialize(msg);

then though before I send is when I send it to my message base class :

   public class ByteMessage : MessageBase
    {
        public byte[] Data;
   }

by using this :

 public void SendOpResponse(int conn, byte[] serializedmsg, int channel)
        {
            var data = new ByteMessage() { Data = serializedmsg };
            NetworkServer.SendToClient(conn, (byte)RtsMessageType.OperationResponse, data);
            Debug.Log("Message Sent");
        }

Then I just do the opposite of course to receive.

   private void RegisterHandlers()
        {
            NetworkServer.RegisterHandler((byte)RtsMessageType.Operation, IncomingOperationHandler);
        }

        private void IncomingOperationHandler(NetworkMessage msg)
        {
            var byteArray = msg.ReadMessage<ByteMessage>();
            var recievedBytes = byteArray.Data;
            var deserial = _noc.DeserializeOperation(recievedBytes);
        }  

        public OperationRequest DeserializeOperation(byte[] deserial)
        {
            var msg = LZ4MessagePackSerializer.Deserialize<OperationRequest>(deserial);
            Debug.Log("Message Deserialized");
            return msg;
        }

Thank you for your help!
Fiction found an error in my code. While I tried yours.

My problem was that I had to create a separate instance of the class before sending it.

I did not consider that the data is sent in a few milliseconds.
Also deleted a class after end of function.

Forgive me for my English … this is an interpreter and not me))
Thanks again!

As long as it is working, that is all that matters, lol.