Exchanging messages between devices and services.

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

In this post I will provide few example which shows how to exchange messages between devices and service. In all examples, we will assume that service is implemented in .NET for Windows System32 (today known as desktop) and device is implemented in .NET for Windows RT. Please note that there are many other ways like REST or SOAP which can be used to connect any kind of two participants. Assuming that we expect a high-scale or even “unknown scale” it will be difficult to connect all this things in internet by leveraging  common techniques. However the scale is not only issue in this context. Think about pushing of messages to device which are not publicly visible (hosted on private IP behind  NAT etc.).
If you want to know more about this please take a look on this post. Clemens has briefly described how “things” might/should work. I strongly believe that we will adopt such or similar ways to connect “things” to each other. Unfortunately we are today probably  bit too early. I learned that Hardware Engineering in context of software evolution is in majority of cases the special world of proprietary software solutions from the point of view of a software engineer. This is just my personal my lesson learned.

Example shown in this post shows communication between participants based on Message API style. They will exchange messages through service bus queues.
To be more concrete the service provides API messaging implemented in WindowsAzure.ServiceBus assembly. The simplification of the more or less same functionality is provided by messaging API for Windows RT in assembly Windows.Messaging.Managed.

However you have to be aware of one important thing, which is by design in these two assemblies different. Windows.Messaging.Managed uses by default DataContractJsonSerializer for serialization of messages (invoke of Send method) and for deserialization of message body (calling of Receive method). In contrast, WindowsAzure.ServiceBus  uses as default serializer DataContractSerializer.
In other words,


Untitled
 

Following example shows how to send the message form service (Windows System32 (desktop)) to device running on Windows RT.

        public static void SendFromServiceToDevice()
        {
           
QueueClient client = QueueClient.CreateFromConnectionString(m_DeviceConnStr, m_qName);
           
           
for (int i = 0; i < 10; i++)
            {
               
var num = new Random().Next();
               
Console.WriteLine("Message {0} sent. {1}", num, i);
               
var msg = new BrokeredMessage("i = " + i.ToString() + ", payload = " + num.ToString(),
                
new DataContractJsonSerializer(typeof(string))) { SessionId = "MySession" };
                client.Send(msg);
            }
        }

As you see the code above inject explicitly  DataContractJsonSerializer which will be used by serialization of the message.
This code will also use SBMP (original native SB protocol) or AMQP protocol (depending on connection string – see amqp overview  and video).
If you send the message this way to device, on the device side you do not have to implement any special message handling. Your code to receive this message is very simple:

public static void ReceiveFromeServiceAtDevice() {
   m_Queue =
new Queue(m_QueueName, m_ConnStr);
   var msg = await m_Queue.ReceiveAsync<string>();
}


But, what if there another service which is implemented as Windows system32 application, which should receive this message?
In this case you cannot receive the same message as you would usually do it. Following code will fail with some very strange SerializationException:

”There was an error deserializing the object of type System.String. The input source is not correctly formatted.”

public static void ReceiveAtServiceFromServiceBAD() {
  var client = QueueClient.CreateFromConnectionString(cs, qName, ReceiveMode.ReceiveAndDelete);
  var m = client.Receive();
}

To make it working you can explicitly specify the serializer, which will be used to deserialize message:

public static void ReceiveAtServiceFromServiceOK() {
  var client = QueueClient.CreateFromConnectionString(cs, qName, ReceiveMode.ReceiveAndDelete);
  var st = m.GetBody<string>(new DataContractJsonSerializer(typeof(string)));
}

Following code shows how to inject serializer in windows store app. As firts, you have to receive message as native Message. The type Message is
simplification of type BrokeredMessage.

public static void ReceiveFromeServiceAtDevice() {

  Message msg = await m_Queue.ReceiveAsync<Message>();
  string strMsg = msg.GetBody<string>(new System.Runtime.Serialization.DataContractSerializer(typeof(string)));

}

Last, but not least is the example which shows how device (windows store app) can inject serializer:

   private async void Button_Click_5(object sender, RoutedEventArgs e){

            Queue queue = new Queue(m_QueueName, m_ConnStr); 

            await queue.SendAsync(new Message(m_Txt.Text, 
            new System.Runtime.Serialization.DataContractSerializer(typeof(string)))); 

}

This post is also related to following article: http://developers.de/blogs/damir_dobric/archive/2013/06/04/messaging-on-windows-rt.aspx


Posted Oct 08 2013, 07:57 PM by Damir Dobric
developers.de is a .Net Community Blog powered by daenet GmbH.