Service Tutorial 4 (C#) - Supporting Subscriptions
Glossary Item Box
Microsoft Robotics Developer Studio | Send feedback on this topic |
Service Tutorial 4 (C#) - Supporting Subscriptions
Writing an application using the Decentralized Software Services (DSS) is a simple matter of orchestrating the input and output between a set of services. Services represent the interface to software or hardware and allow you to communicate between processes that perform specific functions.
This tutorial is provided in the C# language. You can find the project files for this tutorial at the following location under the Microsoft Robotics Developer Studio installation folder:
Samples\ServiceTutorials\Tutorial4\CSharp
This tutorial teaches you how to:
- Support a Subscribe Message.
- Use the Subscription Manager.
- Maintain the Subscriber List.
- Send Notifications.
- Synchronize With a New Subscriber.
See Also:
- Appendix A: Subscription Manager Message Flow
The service written in Service Tutorial 3 will be modified to support subscriptions. |
Prerequisites
This tutorial uses the service written in Service Tutorial 3 (C#) - Persisting State. The service you will create is referred to as ServiceTutorial4. Feel free to start a new project or keep working in the previous project, keeping in mind that some names may differ.
Hardware
This tutorial requires no special hardware.
Software
This tutorial is designed for use with Microsoft Visual C#. You can use:
- Microsoft Visual C# Express Edition
- Microsoft Visual Studio Standard, Professional, or Team Edition.
You will also need Microsoft Internet Explorer or another conventional web browser.
Step 1: Support a Subscribe Message
The first part of supporting subscriptions is to support a Subscribe message.
In the file, ServiceTutorial4Types.cs, add the definition of a Subscribe message and include it in the list of messages supported by the service. The classes SubscribeRequestType and SubscribeResponseType are standard types defined in the Microsoft.Dss.ServiceModel.Dssp namespace.
The definition of Subscribe message:
public class Subscribe : Subscribe<SubscribeRequestType, PortSet<SubscribeResponseType, Fault>>
{
}
After including the Subscribe message to the service's operaions port, it should look like this:
/// <summary>
/// ServiceTutorial4 Main Operations Port
/// </summary>
[ServicePort]
public class ServiceTutorial4Operations : PortSet<
DsspDefaultLookup,
DsspDefaultDrop,
Get,
HttpGet,
Replace,
IncrementTick,
Subscribe>
{
}
In order for the code to be more readable we have expanded the operations port into multiple lines. |
In the file, ServiceTutorial4.cs, add the SubscribeHandler method to the service implementation class.
This handler currently logs the subscriber's address and nothing else. The next step illustrates how to maintain the list of subscribers.
[ServiceHandler(ServiceHandlerBehavior.Concurrent)]
public IEnumerator<ITask> SubscribeHandler(Subscribe subscribe)
{
SubscribeRequestType request = subscribe.Body;
LogInfo("Subscribe request from: " + request.Subscriber);
yield break;
}
The sample file, ServiceTutorial4.cs, is a modified version of Service Tutorial 3 (C#). The lines of code pertaining to the timer port used in Service Tutorial 3 were removed and replaced with the new "Interval=" ServiceHandler Attribute. This attribute schedules a periodic timer event to invoke the handler with the interval specified in seconds (as a double). See example below from ServiceTutorial4.cs: [ServiceHandler(ServiceHandlerBehavior.Exclusive, Interval=1)] public IEnumerator
For this tutorial, we will create a partner (named SubMgr) whose Contract is https://schemas.microsoft.com/xw/2005/01/subscriptionmanager.html. When the service is started, it creates a new instance of this partner. If that creation fails, the service creation also fails and the Start method will not be called. Add the following definition to the service implementation class after the line that defines _mainPort:
Here, the Partner attribute is applied to the _submgrPort field. This _submgrPort field is declared as the SubscriptionManager's main service port. Any message posted to this port will be forwarded to the SubscriptionManager instance created for this service. Step 3: Maintain the Subscriber ListNow that you have a SubscriptionManager as a partner you can send messages to it. Begin by maintaining the list of subscribers. DsspServiceBase provides a method to do exactly what you need. Add the following code in SubscribeHandler just before yield break.
This method sends an Insert message to the SubscriptionManager. The SubscriptionManager then assumes responsibility for managing the list of subscriptions. Step 4: Send NotificationsThe final part of supporting subscriptions is sending notifications to subscribers. Because this service uses the SubscriptionManager, all you need to do is post state changes to the SubscriptionManager. SubscriptionManager sends notifications on to the subscribed partners. There are two places where the state changes, the IncrementTickHandler and the ReplaceHandler methods. When the state is entirely replaced, send a notification to our subscribers with the new service state. DsspServiceBase provides a helper function, SendNotification, that internally sends a Submit message to the SubscriptionManager with the body of the message to send to the subscribers and the action verb (in this case ReplaceRequest). Add the following code to the ReplaceHandler after the line that modifies _state:
Likewise, when the state is updated by the service handling an IncrementTick message, send a notification of this event to the subscribers. Add the following code to the IncrementTickHandler after the call to LogInfo:
The subscription model has a symmetry. The service can notify its subscribers with any state changing message that it can itself process. (In other words, a notification message must be one of the messages listed in the Operations Port). So in the case of this tutorial service, the only two messages that modify the service state are Replace and IncrementTick. Service Tutorial 5 (C#) - Subscribing shows you how to subscribe to this service. Step 5: Synchronize With a New SubscriberThe IncrementTick update does not contain the current tick count, merely carrying the semantic content that the Tick count should be incremented by one. Because of that, a subscriber does not know the tick count, only the number of ticks that have occurred since the subscription started. If you want, you can send the current tick count by sending a Replace notification to new subscribers. Begin by changing the SubscribeHandler method to detect when a new subscriber is successfully added. The SubscribeHelper method works by sending an Insert message to the SubscriptionManager service. This is an asynchronous operation. SubscribeHelper returns a SuccessFailurePort. This is a PortSet that can handle two message types: SuccessResult and Exception. To handle this result, we return a Choice task using yield return. That Choice task then takes two delegates: one which handles the SuccessResult, and one that handles an Exception. When a SuccessResult message is returned, we know that the subscription has been successfully established and we send the current state of the service (as a Replace notification) to the subscriber. If an Exception message is returned, we log this error.
SummaryIn this tutorial, you learned how to:
Appendix A: Subscription Manager Message FlowThe following sequence diagram shows the message flow when ServiceTutorial5 subscribes to ServiceTutorial4. Figure 1 - Subscription message flow between two services.
© 2012 Microsoft Corporation. All Rights Reserved. |