# Using Polling as an Alternative to Callbacks

Because callbacks are, by definition, separated from the original request to which the callback is a response, they appear as unsolicited messages to the client's host. Many hosts refuse unsolicited network traffic, either because they directly reject such traffic or because they are protected by firewalls or other network security apparatus. Clients that run in such environments are therefore not capable of receiving callbacks.

Another requirement for handling callbacks is that the client is persistent by being conversational. If the client is a web application, that is, a JSP page, or a non-conversational web service, it cannot handle callbacks.

In order to allow clients that can't accept callbacks to use your web services, you can supply a polling interface as an alternative. In a polling interface, you provide one or more methods that a client can call periodically to determine whether the result of a previous request is ready. Although the web service or Java control will still be asynchronous in design, the interactions with a client are handled with synchronous (unbuffered) methods.

A typical design of a polling interface will have these three methods:

- A start_request method that the client will call to initiate a request. If the client calls a web service, the start_request method will start a conversation.
- A check_status method that the client will periodically call to check the status of the request. The method returns a boolean value indicating whether or not the request has been handled. If the client calls a web service, the check_status method will continue the conversation.
- A get_results method that the client will call to get the results of the request. The results may for instance be returned as a String or an object of some kind, or null if the request could not be processed successfully. If the client calls a web service, the get_results method will finish the conversation.

Notice that a client using a polling interface needs to periodically check the status of the request, because the web service or Java control cannot notify the client when its request has been processed. Also notice that the three methods will not be buffered. The check_status and get_results methods do not return void and cannot be buffered, while the start_request method cannot be buffered because you need to ensure that this method has been handled before the check_status is handled. (Remember that the relative handling order of buffered and unbuffered methods is uncertain. For more information, see Using Buffering to Create Asynchronous Methods and Callbacks.)

There are several other ways to implement a polling interface. The following example taken from the source code of the Conversation.jws Sample web service shows one such variation:

    public class Conversation {
        /**
         * @common:operation
         * @jws:conversation phase="start"
         */
        public void startRequest()
        {
             ...
        }
        /**
         * @common:operation
         * @jws:conversation phase="continue"
         */
        public String getRequestStatus()
        {
            ...
        }
        /**
         * @common:operation
         * @jws:conversation phase="finish"
         */
        public void terminateRequest()
        { }
    }

A client uses the startRequest method to initiate a request from a conversational web service. The client then calls getRequestStatus periodically to check on the result. As before, the client is free to perform other processing between calls to getRequestStatus. The getRequestStatus method returns an indication that the request is pending until the request is complete. The next time the client calls getRequestStatus after the request is complete, the result is returned to the client. The client then calls terminateRequest to finish the conversation.

Related Topics

Web Services Development Cycle

Getting Started: Using Asynchrony to Enable Long-Running Operations

Designing Conversational Web Services