Skip to content

Send and recieve complex objects

Ca5an0va edited this page Dec 15, 2017 · 4 revisions

SignalGo is internally using json for default serialize and deserialize tasks on variuos data structure. But json.net can't serialize and deserialize all types. For example, System.Drawing.Bitmap or Image are unsupported.

SignalGo has a built in SerializeHelper static class with 2 Actions:

  • SignalGo.Shared.Helpers.SerializeHelper.HandleSerializingObject
  • SignalGo.Shared.Helpers.SerializeHelper.HandleDeSerializingObject

With this class, and actions, you can easily set up the SignalGo serialization/deserialization plan for the unsupported types (you are telling Signalgo: "when you find this object with this type you must work this way".

Let's make a practical example: you have a class like this (coming from Entity Framework data model for example):

    public class Person
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public string Address { get; set; }
        public int Age { get; set; }
        public System.Drawing.Bitmap Picture { get; set; }
    }

Now consider you have a List with 10 items and need to broadcast this list to client. The Bitmap type (Picture property) isn't handled by json.net ...how to solve? Simple! Tell Signalgo how to handle Bitmap type with SerializeHelper class!

Follow these easy steps:

Step 1

Into the Shared Project (the one hosting Interfaces for Server Methods and Client Methods: in this example we named it SignalGoSharedProject) you can create a static class
CustomSignalgoSerializers with a method InitializeSignalGoSerializers (you can name class and method as you want):

EXAMPLE 1: we want type BITMAP handled as byte[]

 public static class CustomSignalgoSerializers 
    {
        public static void InitializeSignalGoSerializers()
        {
            try
            // This action tells SignalGo how to handle serialization of type BITMAP
            {
                SerializeHelper.HandleSerializingObject<Bitmap, byte[]>((obj) =>
                {
                    using (var stream = new MemoryStream())
                    {
                        obj.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                        return stream.ToArray();
                    }
                });

            // This action tells SignalGo how to handle deserialization of type BITMAP
                SerializeHelper.HandleDeserializingObject<byte[], Bitmap>((obj) =>
                {
                    using (var stream = new MemoryStream(obj))
                    {
                        return new Bitmap(stream);
                    }
                });

                //Others custom serializers/deserializers HERE for other types
                // SerializeHelper.HandleSerializingObject<Image, byte[]>((obj) => *your code to handle conversion*
                // SerializeHelper.HandleDeSerializingObject<byte[], Image>((obj) => *your code to handle conversion*
            }
            catch (Exception)
            {
                throw;
            }
        }
    }

EXAMPLE 2: we want type BITMAP handled as base64 string

 public static class CustomSignalgoSerializers 
    {
        public static void InitializeSignalGoSerializers()
        {
            try
            // This action tells SignalGo how to handle serialization of type BITMAP
            {
                SerializeHelper.HandleSerializingObject<Bitmap, string>((obj) =>
                {
                    obj.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                        var bytes = stream.ToArray();
                        string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
                        return base64String;
                    }
                });

            // This action tells SignalGo how to handle deserialization of type BITMAP
                SerializeHelper.HandleDeserializingObject<string, Bitmap>((obj) =>
                {
                  var bytes = Convert.FromBase64String(obj);
                    using (var stream = new MemoryStream(bytes))
                    {
                        return new Bitmap(stream);
                    }
                });

                //Others custom serializers/deserializers HERE for other types
                // SerializeHelper.HandleSerializingObject<Image, byte[]>((obj) => *your code to handle conversion*
                // SerializeHelper.HandleDeSerializingObject<byte[], Image>((obj) => *your code to handle conversion*
            }
            catch (Exception)
            {
                throw;
            }
        }
    }


Step 2

In Program.cs (or elsewhere) of both your Server and Client app add this code:

 static void Main()
            {
            SignalGoSharedProject.CustomSerializers.InitializeSignalGoSerializers();

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new F_client());
            }

In this case we're considering a WinForm App (for windows service or console it's the same: the important is that this code must be executed before starting the server and before client connects to it)

Step 3

Run your server method (in this example example into a button event) that sends to client the 10 item List once connected:

    private void button2_Click(object sender, EventArgs e)
        {
            //Declare a connector for client
            var connector = new ClientProvider();
            string serverAdress = "http://192.168.1.10:8080/SignalGoTest";
            //Connect to server
            connector.Connect(serverAdress);
            //Register callbacks
            var callbacks = connector.RegisterServerCallback<ClientMethods>();
            // Register Server methods
            var ServerService = connector.RegisterClientServiceInterface<IServerMethods>();
            // Get from Server List<Person> having the Péroperty Picture of type BITMAP 
            var listPersons = ServerService.SendList(true);
            // bind Picture of item 0 to a PictureBox and you will show the Bitmap!
            pictureBox1.Image = listPersons[0].Picture;
        }

In the pictureBox1 you will see the bitmap correctly deserialized.

Conclusions:

In SignalGo is extremely easy to handle serialization/deserialization of custom or unsupported types. You don't need to touch your Class (or data model), just tell SignalGo how to handle them (via SerializeHelper class) and SignalGo will do the job for you!