To run DSS services you can either use the DssHost.exe tool or create your own application to host a DSS node. In the Hosting Tutorials we provide samples of such applications. You can use the DssEnvironment.dll assembly and the DssEnvironment static class to initialize the DSS runtime within an application of your choice or a .NET Windows Service.
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\HostingTutorials\Tutorial2\CSharp
This tutorial teaches you how to:
Prerequisites
This tutorial uses the service written in Service Tutorial 1 (C#) - Creating a Service.
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.
Querying Services within a Hosted DSS Node
The Microsoft Visual Studio solution for this sample is called HostingTutorial2.sln and can be found in the sample location mentioned above. Open the solution file or create a new C# Console Application project in Visual Studio and replace the contents of the source file with the following code. You will also need to reference the proxy assembly of ServiceTutorial1 service in the project.
The following code sample demonstrates hosting a DSS node and querying services. The application runs a DSS node with the ServiceTutorial1 manifest and then makes a request to the Service Directory for the ServiceTutorial1 service. If the service is found, it sends a Get request to ServiceTutorial1 service to retrieve its state and logs the value of the Member property of ServiceTutorial1State object. If any of the requests fails during this process the application will log an error, shut down the DSS node and exit.
using System;
using System.Collections.Generic;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core;
using Microsoft.Dss.Hosting;
using Microsoft.Dss.ServiceModel.Dssp;
using st1 = RoboticsServiceTutorial1.Proxy;
namespace HostingTutorial2
{
class Program
{
// Used to set exit code
static int _status = 1;
/// <summary>
/// Main entry to the program
/// </summary>
/// <returns>0 if program succeeds, otherwise a value greater than 0</returns>
static int Main()
{
try
{
// Initialize DSS node on port 50000 (HTTP) and 50001 (TCP) with a manifest
// starting an instance of the Service Tutorial 1 service.
DssEnvironment.Initialize(50000, 50001,
LayoutPaths.RootDir + LayoutPaths.SampleDir + @"config\ServiceTutorial1.manifest.xml");
// Spawn RunTask
Arbiter.Activate(DssEnvironment.TaskQueue, Arbiter.FromIteratorHandler(RunTask));
// Wait here until DSS Environment has been shut down
DssEnvironment.WaitForShutdown();
// Exit program
return _status;
}
catch
{
return -1;
}
}
/// <summary>
/// The runtask function uses iterators to mimic sequential programming even though
/// it is actually running asynchronously.
/// </summary>
/// <returns></returns>
static IEnumerator<ITask> RunTask()
{
// Issue query for an instance of Service Tutorial 1 service
var queryResultPort = DssEnvironment.DirectoryQuery(st1.Contract.Identifier);
// yield to either success or failure result
yield return queryResultPort.Choice();
// after the yield check which response was received. This is safe to do since
// we have already waited for the choice to complete
ServiceInfoType success = queryResultPort;
if (success == null)
{
// Request must have failed. Extract fault message from port
W3C.Soap.Fault failure = queryResultPort;
DssEnvironment.LogError("Could not find service tutorial 1");
DssEnvironment.LogError(failure.ToString());
// exit iterator
yield break;
}
// Request succeeded.
DssEnvironment.LogInfo("Found service tutorial 1 service: " + success.Service);
// Now create service forwarder port so we can post messages to the
// service tutorial 1 instance
var serviceTutorial1Port =
DssEnvironment.ServiceForwarder<st1.ServiceTutorial1Operations>(new Uri(success.Service));
// Send a GET request to service tutorial 1
var getResultPort = serviceTutorial1Port.Get();
// wait for either success or fault
yield return getResultPort.Choice();
// check if we have success response
st1.ServiceTutorial1State getResponse = getResultPort;
if (success != null)
{
// GET Request succeeded
DssEnvironment.LogInfo("Service Tutorial1 state: " + getResponse.Member);
// Set exit code to 0 for success
_status = 0;
}
else
{
// GET Request failed.
DssEnvironment.LogError("Could not retrieve state.");
}
// Shut down runtime
DssEnvironment.LogInfo("Run task completed");
DssEnvironment.Shutdown();
}
}
}
When you run the application, you can browse to http://localhost:50000 to see the DSS node running.
In this tutorial we covered: