When you see the title of this article, you will probably think that idea of the service which runs on device like surface sound a bit strange or even crazy.
But it is not strange, it is just crazy.
If you think about service as a peace of code running on some server and supposed to be consumed by some consumer, you are probably right.
The idea of a service which is running on the side of consumer is kind of wrong.
But if so, we should stop to think traditional way. One software developer should always innovate things.
Assume the service is not supposed to be consumed by consumer. Think about service as a piece of code which can be accessed remotely to observer some data.
In the time of cloud computing we are more and more pushed in direction of totally distributed participants.
Participant is in this context defined as any application which connects via network to the system and participate on data exchange.
In such environment (called cloud) every participant can play a role of a service. Following picture show a number of devices.
If connected together they would build mesh of devices.
Most devices will not provide power of computing, but they can do many interesting task.
For example every simple smart phone can be used as GPS device, which can be accessed remotely. Similarly one microscope can be remotely access to provide current image.
Following this example, we could build the service which runs on smart phone and delivers in some interval the GPS location of the smart phone.
Or similarly, we could build the service to receive remotely command and provide Geo Location data on demand.
In both cases we have to explain device to act as a service. In this article we are more interested on accessing of a device remotely, because it is more difficult.
For the rest of this article we assume that device is running on Windows RT platform. In other words we want to build the WinRT app, which acts as a service.
The idea is to build the service which symbolically implement application which can invoke some operation at the service side:
GeoLocation serviceProxy.GetDeviceLocation(instanceOfTypeX);
|
On the service side we would usually implement operation as:
GeoLocation GetDeviceLocation(TypeX instance) { // service code … return geoLocation; } |
TypeX is some input argument in the operation, which the service logic might use.
This service could be implemented as SOAP service (for example in WCF) or REST service by using of WebApi. In a case of SOAP service we would
(usually without of knowing it) implement Web Service API style called RPC.
In a case of WebApi we would implement resource API style. Most people speculate about which one is better or cooler.
Due explicate strong dependency of Consumer to the Service, in the world of total distribution I would say booth are not the best choice.
We should rather try to achieve the Message API style. Unfortunately I’m going to explain in this article why.
The caller of the hypothetical service shown above service operation need to obtain some service URL. Unfortunately such URL is the biggest practical issue in this scenario.
To have URL of the service which runs on device, it would mean that service has an IP address. This is not impossible to make happen, but it complicates the environment unnecessary.
In the cloud mesh environment we usually also assume that participant in the systems are moving (mobile). Due this assumption they will not only change their location, but also their network (IP).
In this case no admin will run behind device to setup infrastructure (firewall, VPN and Co.).
So, we need a solution which assumes that devices will at least have an outbound connection to internet via HTTP:80.
This is our only requirement.
Here is how to do it.
As next create Windows Store App in Visual Studio and add NuGet reference to package
WindowsAzure.Messaging.Managed.
This package brings messaging functionality in the WinRT platform. For more information take a look
here. Then we are going to implement the message listener which will listen for messages.
In our case the message will hold the instance of type TypeX. Following example shows how to do this.
m_QueueListener = new Queue(“myservice/listener”, m_ConnStr); private void StartServiceListener() { m_QueueListener.OnMessage((msg) => { try { if (msg != null){ TypeX instanceOfTypeX = msg.GetBody<TypeX>(); GeoLocation loc = service.GetDeviceLocation(instanceOfTypeX); sendResponse(loc); } } catch { } }); }
|
On WindowsRT we could start the service as a background worker if the application does not need UI. Somewhere in the code service will be
started by invoking of method
StartServiceListener() .
That method enters the message pump loop, which listens for mes
sages sent to the queue “
myservice/listener ”.
After the message is received it is materialized to instance of type TypeX and passed as input argument to implementation of GetDeviceLocation().
This method plays the role of the service operation from the point of view of the caller. But notice, unlikely to SOAP RPC we use the message as a contract.
It is even more interesting, that caller and service are totally decoupled. It means you can stop the service and the message will still arrive after the service is started,
even if the service is started on some other node implemented in JAVA or anything else.
After the operation has completed we can send the response to the response queue by invoking method sendResponse.
Following example shows how to implement this method:
m_QueueResponse = new Queue(“myservice/receiver”, m_ConnStr); private void sendResponse(object response) { await queue.SendAsync(new Message(response)); }
|
Now you can implement the consumer of this service in almost any technology. Windows Azure Service Bus supports at the moment of writing of this article following protocols:
- SBNP (native TCP protocol used with .NET SDK)
- AMQP native TCP protocol introduced in Service Bus 2.0
- HTTP/REST
This means that two participant can communicate to each other even if they are implemented in different technologies and/or talk different protocols.
However, before queues can be used, somebody have to create them. Following example shows how to:
- Create queues
- Create the key
- Setup SharedAccessKey permissions
- Create connection string
Note that this example is build in .NET for Desktop version of Windows.
private static void prepareSystem() { string key = SharedAccessAuthorizationRule.GenerateRandomKey(); if (namespaceManager.QueueExists(m_qName)) namespaceManager.DeleteQueue(m_qName); QueueDescription qDesc1 = new QueueDescription(m_qName); qDesc1.Authorization.Add(new SharedAccessAuthorizationRule("device_send_listen", key, new AccessRights[] { AccessRights.Listen, AccessRights.Send })); var connStr = String.Format("Endpoint=sb://YOURNAMSPACE.servicebus.windows.net/; SharedAccessKeyName= device_send_listen;SharedAccessKey={0}", key); } |
The code shown above shows how to create a queue with Listen and Send permission. We could also append permissions more granularly if required:
qDesc1.Authorization.Add(new
SharedAccessAuthorizationRule("device_send", key2,
new AccessRights[] { AccessRights.Send })); pa permissions:
qDesc1.Authorization.Add(new
SharedAccessAuthorizationRule("device_send", key2,
new AccessRights[] { AccessRights.Send }));
Examples and ideas shown in this article are today all supported by Windows RT and Windows Azure Service Bus. As a developer you will agree, that this might not be a big implementation deal.
However, most of as will probably not immediately notice that examples from above hide in detail huge shift in thinking about how to connect things.
If you have carefully read, you figured out that we use message API style instead of all popular tradition API styles.
This is not new idea, but right now can be achieved in its full power. Notice also that queue mechanism bring on table things like CQRS and support for almost all important integration patterns (i.e. Retry, Pub/Sub etc.). All this helps you to build powerful applications in shorter time.
Last but not least, note that can even communicate through closed inbound connections.
I think, this will open a wide range of new innovations soon.
Posted
Dec 20 2013, 06:50 AM
by
Damir Dobric