Custom Message Serialization in C#

Options
MartinCA
edited May 2015 in DotNet
Hey everyone,

I was wondering if it's possible and supported to send custom messages in the form of byte buffers using the C# SDK.

I was looking at the interface for SocketServer.PeerBase and found these methods, which is essentially what I'm looking for
protected virtual void OnReceive( byte[] data, SendParameters sendParameters );
protected internal virtual void OnSend( int bytesSend );
protected SendResult SendData( byte[] data, SendParameters sendParameters );

Only problem is that I can't seem to find the equivalent in the client libraries, neither in Client.PhotonPeer nor in IPhotonPeerListener.

So, the questions are:
1. Is it possible using the C# SDK? Am I just missing something here?
2. Is it a supported feature? Didn't get around to disassembling stuff yet, so I'm guessing that beyond PhotonPeer lies the unmanaged layer - is there any way to add this feature using interop and some super glue?

I don't want to re-invent any wheels here, hence the supported question. The main thing I'm concerned with and I want to resolve is the fact that the byte-object map for message data generates lots of garbage and mem copies - some of it can be resolved by reusing preallocated dictionaries, but some is inevitable due to the boxing/unboxing involved in casting value types to objects. The second motive here is that I would love to reuse parts of an existing serialization protocol.

Any information would be appreciated :)
Thanks!

Comments

  • Tobias
    Options
    Sorry for the late reply.
    In theory it's possible to have "raw" messages but like you already found, it's not in the client SDKs. It wasn't such a requested feature so far, so we skipped adding it in favor for using events which can now contain byte[] as alternative to Hashtable and all other serializable datatypes.
    Are you still on this?
  • JasonG
    Options
    I would really like to see support for raw byte arrays. Right now it seems the only way to support native byte arrays for custom serialization is to do something similar to the code below...however it feels a bit like a hack, but it works...

    var requestBytes = Serializer.Serialize(serverMessage);
    var parameters = new Dictionary<byte, object> { { 0, requestBytes } };
    var operationRequest = new OperationRequest(0, parameters);
    Peer.SendOperationRequest(operationRequest, new SendParameters());

    Then in OnOperationRequest you would take the bytes and de-serialize them into your custom message format. Not sure this is the best approach...

    So bottom line is, I would love to have raw byte arrays supported. Is there a place we can go for feature requests or this done here on the forums?
  • Tobias
    Options
    I'm just writing to tell you that we understand your post as feature request and have it on our list to check and implement when we find some time.
    That is obviously not clear when we don't react at all.

    The Peer.SendOperationRequest() is a method you'd use between servers, so I want a guy from the server side to give his input, too. I don't think it's terribly difficult to support but we are also trying to finalize a Photon Server 4 release.

    In short: Consider your request noted!
  • chvetsov
    Options
    JasonG wrote:
    I would really like to see support for raw byte arrays. Right now it seems the only way to support native byte arrays for custom serialization is to do something similar to the code below...however it feels a bit like a hack, but it works...
    We noted your request.
    but I just intersted why you prefer to use raw byte arrays instead of current way of doing this?
  • Trixer
    Options
    I had some issues with seralization of custom objects too.. Let me show you what I did to ensure that I could make an object, use it server or client side, the way I wanted to. Then seralize it to send over the line when needed. Its not the most elegant way but it works for my needs.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Photon.LoadBalancing.Common.Persistence
    {
    public class Character
    {
    public string CharacterId { get; set; }
    public string Name { get; set; }
    public string OwnerID { get; set; }

    public Hashtable toHashTable()
    {
    Hashtable CharacterHashTable = new Hashtable();
    CharacterHashTable["CharacterId"] = this.CharacterId;
    CharacterHashTable["Name"] = this.Name;
    CharacterHashTable["OwnerID"] = this.OwnerID;
    return CharacterHashTable;
    }

    public Character toClass(Hashtable CharacterHashtable)
    {
    Character PlayerCharacter = new Character();

    PlayerCharacter.CharacterId = (string)CharacterHashtable["CharacterId"];
    PlayerCharacter.Name = (string)CharacterHashtable["Name"];
    PlayerCharacter.OwnerID = (string)CharacterHashtable["OwnerID"];

    return PlayerCharacter;
    }
    }
    }
  • Trixer
    Options
    To follow up, you could use the approach above to make a message class and send it to and fro as needed.