Serialization problem

Viktor
edited December 2010 in Photon Server
Hello, how can i send custom objects as parameters in operation responces or events. I tried implementing ISerializeble but i think photon internaly uses something different. Lets say i vant to send something like this:
public class RoomDTO
    {
        public RoomDTO() { }
        public RoomDTO(string name, int maxPlayerCount, int playerCount)
        {
            Name = name;
            MaxPlayerCount = maxPlayerCount;
            PlayerCount = playerCount;
        }

        public string Name { get; set; }
        public int MaxPlayerCount { get; set; }
        public int PlayerCount { get; set; }        
    }
It's a very simple object. Can I somehow send it?

Comments

  • As a quick solution just serialized it using BinaryFormatter and send it as byte array and deserialized it on the other side as object.
  • Photon uses it's own serialization.
    To send a custom object you do currently have two options:
    1) Serialize it first, for example like you did with the BinaryFormatter. The BinaryFormatter is not a solution for clients that do not use C# or .NET.
    2) Convert the object into a hashtable and send the hashtable (e.g. keys = property names or byte codes and values = property values)
  • Boris wrote:
    The BinaryFormatter is not a solution for clients that do not use C# or .NET.
    But for example on native Clients you can achieve the same result for primitive datatypes by simply doing a cast and this way communicate with the .NEt clients even on custom binary data. We had to do this for Ping Tanks before floating point datatypes have been added to the protocol: cast the float to int, send it and cast it back on the other side and the server in between for it's gamelogic simulized the cast from float to int and back by using int->Binary-Converter->float and vice versa, Same way you can of course cast a flaot or int or any other primitve type into a byte* and send it as byte-array.
    For objects it gets more complicated for crossplatform and there 2) would be the easiest solution and as you in most cases do not need all the data from an object, 2) would be the less expensive variant in terms of network traffic for objects in most cases (at least if you use byte-keys and not miles-lon string keys for the Hashtable).
  • It depends a bit on what you binaryformat. if you just do some numbers, then it works yes but for that you don't need binary formatter in .NET either.

    but if you serialize classes and structs then it will fail misserably if you try to do with anything but .NEt <-> .NET
  • dreamora wrote:
    It depends a bit on what you binaryformat. if you just do some numbers, then it works yes but for that you don't need binary formatter in .NET either.

    but if you serialize classes and structs then it will fail misserably if you try to do with anything but .NEt <-> .NET
    Yes, you could of course simply use unmanged C# and then cast, but I don't know many C#-Coders, who would do that.
  • Pretty surely not me ;)
    Messing in the unmanaged realm is always painfull.


    Before doing that you would see me use xml/json + lzma ;)
  • Argh, xml!
    Please skip xml and jump to json if you must ;)
  • hehe :)
    Both have benefits, xml cause its just there, json cause its uncompressed a bit smaller but also 2x as painfull to look at in plaintext and only half the json .net libraries work with unity for example, even less if we talk about mobile or webplayer (there its jsonfx and with some luck litjson)

    Well after lzma compression the difference between the two is forgetable as the part that causes the size is not the tags but the text inbetween the tags thats changing on each new tag of the same type
  • Uncompressed xml is one of the easiest ways to kill your bandwith. Every byte of raw payload easily ends up in 20, 50 or even more times the size with xml. Compressing it every time you send your data (as it is changing everytime, otherwise you would not have to send it again) and decompressing them on receiving (which is the worse part, as in most cases you will receive much more than you send in awell-designed client-server solution like Photon) will probably affect performance more than only a little bit for devices like the iPhone (especially the older generations). The best really is, to put the stuff into an Hashtable with byte or short keys to minimize the amount of data, you have to send. If you want to send content of your custom objects, you would have to access the content directly anyway, as no method can know, what kind of data is in your custom classes, unless the method is specifically designed for your classes (and if you would do that for xml or json, you could also just serialize your objects to byte-arrays with less work and much more efficient in terms of bandwith).
  • Fully agree on that and I'm well aware of it.
    But in case you need object instance serialization its likely still the best if not only reasonable approach cause binaryformatter and alike will fail from .NET to unmanaged and going through the managed <-> unmanaged layer for both directions will kill more performance due to the impact on memory handling etc than using lzma or some lightweight zip.

    As for "knowing whats in there": thats actually very well possible, thats what serialization is for in .NET and what it is used for, to handle arbitary data and serialize them to another representation with the possibility to serialize it back later on. With C++ on the other end you would naturally need to unserialize it manually, but something like ObjC there can unserialize it as easy as .NET can thanks to how ObjC works.


    But I agree: its not really acceptable "to not know and especially not optimize" what you send through so the situation of arbitary data should never arise on anything but webservice communication.
  • Check this one.....Net Serialization basics

    Walsh
  • For serialization I use Google Protocol Buffers (sure you need to rethink you entities). Flatbuffers are also great at this point. Don't ever user flat strings like xml because the stream gets really huge and serialization / deserialization is very slow.