Reliable and Durable Messaging


Reliable messaging helps protect an application from transient communications problems between nodes by automatic failure detection and transient failure recovery. Indigo normally hides these recoverable errors from your application, allowing you to concentrate on developing your functionality rather than writing lots of code to deal with network reliability issues. Reliable messaging provides certain assurances about the delivery of messages to the applications, and it either fulfills the assurances or informs the application it was unable to fulfill them.

Durable messaging addresses a different problem. Durable messaging insulates applications from node failures at the messaging endpoints that are hosting the application by providing durable storage at the messaging endpoints. This allows Indigo to restore a communications session between messaging endpoints after a failure.

A dialog is the key Indigo abstraction that provides reliable message- based communication between Indigo services and other application endpoints. A dialog is a reliable, bi-directional , session-oriented message exchange between two endpoints and essentially consists of the state at these two endpoints. Dialogs can be configured to provide a variety of communication requirements, from a tightly coupled, exactly once, in-order delivery to a more loosely coupled , asynchronous style of delivery.

Reliable messaging between two endpoints requires that each of the endpoints store information about the state of the dialog between them. Indigo stores the state of a dialog in a dialog store at each endpoint. The store allows the objects representing that state to disappear and Indigo can recover the dialog. A durable store provides the ability to recover the dialog. When either the client or the server process that hosts the dialog terminates, it can come back at a later time and continue the dialog from where it left off. Durable storage of dialog state thus makes recovery from process or node failure possible. When the storage is not durable, the objects representing the dialog state are retained only in memory and the dialog will be lost in the event of node failure.

A dialog channel provides the delivery assurances for each endpoint of the dialog. This interface provides state management at each dialog endpoint and the methods to manage messages in the send and receive buffers.

Defining a Dialog-Based Service

I need to make only one major change to the previous service application for it to operate using a dialog. Instead of applying the DatagramPortTypeAttribute to the Web service class, I need to apply the DialogPortTypeAttribute to the class, as shown in the following example. The DialogPortTypeAttribute requests Indigo to establish a session between an instance of this service class and the client who created it. All subsequent communication from and to the client uses the same service instance.

 using System; 
using System.Globalization;
using System.MessageBus;
using System.MessageBus.Services;

namespace WiseOwl {
[DialogPortType (Name="Time",
Namespace="http://www.wiseowl.com/WebServices")]
public class Time {
[ServiceMethod]
public string GetUtcTimeAndDate(string culture) {
Console.WriteLine ("Client requested UTC time for culture {0}", culture);
CultureInfo ci = new CultureInfo (culture);
return DateTime.UtcNow.ToString ("F", ci);
}
}
}

The client could pass an object or an interface as a method parameter to this service. The service could subsequently call methods on the client s object or interface implementation to initiate callbacks to the client. Using a dialog produces a stateful, persistent session between the client and the service.

The client application for this dialog-based service is also nearly identical to my original Web service client application. In the following example, the CreateChannel call creates a session from the client to the service:

 using System; 
using System.Threading;
using System.MessageBus;
using System.MessageBus.Services;
using www_wiseowl_com.WebServices; // The imported service namespace

public class Client {

private static AutoResetEvent doneEvent = new AutoResetEvent (false);

public static void Main(string[] args) {
string culture = "en-US";
if (args.Length > 0) culture = args[0];

// Load the default service environment, called "main".
ServiceEnvironment se = null;

try {
se = ServiceEnvironment.Load();

// Retrieve the ServiceManager from the default environment
ServiceManager sm =
se[typeof(ServiceManager)] as ServiceManager;
if (sm == null)
throw new Exception ("ServiceManager is not available.");

// Start the service environment.
se.Open();

// Create a proxy channel that points to the service to call.
Uri uri = new Uri("soap.tcp://localhost:46000/TimeService/");

ITimeChannel channel = (ITimeChannel)
sm.CreateChannel(typeof(ITimeChannel), uri);

Console.WriteLine(channel.GetUtcTimeAndDate (culture));

Console.WriteLine("Press enter to stop this client...");
Console.ReadLine();

// Either the client or the service can initiate showdown of the session
// by calling IDialogPortTypeChannel.DoneSending

// First, register for the Done event
channel.Done += new EventHandler (DoneHandler);

// Now, initiate the shutdown
channel.DoneSending();

// Now, wait for the shutdown to complete
doneEvent.WaitOne ();
}
catch (Exception e) {
Console.WriteLine (e);
}
finally {
if (se != null) se.Close();
}
}

static void DoneHandler (object sender, EventArgs e) {
doneEvent.Set();
}
}

Because I decorated the definition of the service with the DialogPortTypeAttribute , the Wsdlgen utility produces a different definition of the ITimeChannel interface definition. The class that implements the interface must also implement the IDialogPortTypeChannel interface, resulting in the client and service using a dialog-based communication channel.

Finally, either the client or the service can initiate an orderly shutdown of the session by calling the IDialogPortTypeChannel.DoneSending method. The application must then wait for the Done event before terminating. The previously listed client does this after you press Enter to allow the client application to shut down.




Introducing Microsoft WinFX
Introducing WinFX(TM) The Application Programming Interface for the Next Generation of Microsoft Windows Code Name Longhorn (Pro Developer)
ISBN: 0735620857
EAN: 2147483647
Year: 2004
Pages: 83
Authors: Brent Rector

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net