Skip to main content

Closing WSIT Reliable Messaging Connections

Posted by mikeg on January 24, 2007 at 12:37 PM PST

Most Reliable Messaging implementations in Web Services stacks, including the ones in Sun's WSIT and Microsoft's WCF are designed to operate "under-the-hood" with little or no effort required from client or server application programmers.

There is one case where it is sometimes important for a client application programmer to communicate with the Reliable Messaging system. A Reliable Messaging connection requires both a client and endpoint to maintain state related to the connection. There is no automatic way for the runtime components to know when a client has finished using the connection, so an API (which I'll describe shortly) is provided for the purpose. If the client programmer uses the API, it allows the client runtime to send a WS-RM TerminateSequence message to the endpoint, so both client and endpoint runtimes can do an orderly shutdown of the connection, and discard any resources associated with it.

This is analogous to the usual database programming model, where Connection objects have close() methods that perform a similar function.

The JAX-WS 2.1 interface with the close() method (it's only method) is com.sun.xml.ws.Closeable. Every instance of a JAX-WS 2.1 client, whether it is a Proxy or a Dispatch implements Closeable, so the code:


((Closeable)client).close();

always works, although it sometimes will have no effect. Calling the method provides a way for WSIT components, such as Reliable Messaging and Secure Conversations to do clean-up activities related to the client instance.

Sometimes calling close() can be avoided without harmful effects. Every RM endpoint has a timeout interval. While a client is "still around", it will occasionally send messages to the endpoint to prevent a timeout, but if the client "goes away", the timeout will be reached, and the endpoint will assume that the connection is "closed".

There is another very important benefit to calling close, though. Consider the program:


public static void main(String[] args) {

PingService service = new PingService();
PingPortType port = service.getPingPort();

port.ping();
}

Suppose that when this program is run, the request message for port.ping() is lost in the network. The way that a Reliable Messaging client does its job is to periodically check which messages have been acknowledged by the endpoint and and resend the ones that have not been. In this case, however, the end of the program will be reached before this can happen!

This can be fixed by adding the call to close():


public static void main(String[] args) {

PingService service = new PingService();
PingPortType port = service.getPingPort();

port.ping();
((Closeable)port).close();
}

By default, the call to close() will not return until all messages have been acknowledged. This means that the end of the main() method will not be reached until the request has been resent as many times as necessary for it to be acknowledged.

It is possible to override this default behavior. WSIT has a client-side Reliable Messaging setting called CloseTimeout.
If non-zero, it is the interval (in milliseconds) that the client runtime will block waiting for a call to close() to
return. When the timeout is reached, close() will return and a SEVERE log message will be emitted announcing the likelihood that messages have been lost.

In summary. There is com.sun.xml.ws.Closeable interface with a close() method that is implemented by every JAX-WS 2.1 client.
There is usually some benefit to using it and in a few cases, it is crucial. It never hurts to call it, even if the client does not use Reliable Messaging, so to be safe, it is a good programming practice to always call it.

Related Topics >>