Discover an approach to efficiently communicate with a Web service asynchronously.
When designing applications for consuming Web services, the response time needs to be taken into consideration. If the Web service happens to be on a remote server in an Internet scenario, the response times could be quite high due to heavy network traffic. Or, if the function call itself takes some time to return the response due to heavy processing involved, the response time would be high. A well-designed client application should not wait for the response for so long. It should manage its Web method calls efficiently, especially when there are multiple calls.
The ASP.NET Framework does provide support for accessing a Web service asynchronously. The user can wait until the request completes, can block on the WaitHandle, or wait for a callback function to be invoked. However, WSE 2.0 provides a potentially more powerful way of communicating with a Web service by using WS Addressing. In this white paper, you will see an approach to efficiently communicate with a Web service asynchronously.
WSE 2.0 is a .NET component that can be downloaded and installed into the .NET Framework. WSE is a Soap Extension that manipulates SOAP messages on both the client side and the server side if implemented in both. It provides a way to communicate by using industry standard SOAP messages, which in turn allows for interaction with Services implemented in other technologies. WSE v2.0 has some classes that allow standardized SOAP messages to be sent based on WS-Addressing, WS-Messaging, and the rest of WS-* specifications. This white paper discusses the SoapReceiver and SopaSender classes. The SoapReceiver class implements IHTTpHandler, which is a part of the Microsoft.Web.Services2.Messaging namespace.This class has a Receive
method that passes the SOAP message as an input parameter whenever a HTTP Request or Response occurs. SoapSender is used to send messages by specifying the URI of the destination.
ASP.NET Web Services Using HTTPHandler
The HTTPHandler object is called by the HTTPApplication object whenever a request or response comes in or out of an ASP.NET Web page. The Handler is registered in the application configuration file. Once it is registered, every time a request comes for the specified ashx file, the code in the HTTPHandler is executed.
Here is a sample snippet of code for registering the HTTPHandler:
AsyncWebClient" path=" *.ashx" verb="*" />
The code in AsynReceiver class can be tuned to handle the request/response for the Web page.
When a message is sent using WSE 2.0, it adds the required WS-Addressing message information headers. Inside the Web service, a SoapReceiver can be implemented that can use the <wsa:ReplyTo> reference as the target for response messages.
A client application can send a message to a Web service and then continue with other tasks. The server application would send a response back to the client when it is done with the processing. The client would implement its own HttpHandler using SoapReceiver class to listen for the response from the service.
WSE 2.0 provides two classes to send and receive SOAP messages; SoapReceiver and SoapSender.
The client application implements a listener that listens to the response sent by the service. This is done by implementing and registering a class that implements SoapReceiver.
public class AsynReceiver: SoapReceiver
public AsynReceiver ()
protected override void Receive (SoapEnvelope envelope)
// the response from the service is handled here.
The Receiver class is registered in web.config as follows:
AsyncWebClient" path="*.ashx" verb="*" />
A request is made to the service by sending a SOAP message using the SoapSender class as follows:
EndpointReference epDestination =
SoapSender sSend = new SoapSender();
SoapEnvelope reqEnv = new SoapEnvelope ();
//specify the destination address
reqEnv.Context.Addressing.ReplyTo = new ReplyTo(uriDestination);
reqEnv.Context.Addressing.To = new To(epReceiver.Address );
reqEnv.Context.Addressing.Action = new Action (string);
sSend.Destination = uriReceiver;
In the SoapMessage, the ReplyTo address is specified so the calling service knows where to send back the response. A unique Guid is appended to the message to track the messages. This Guid is kept in the message for the entire request and response sequence.
Web Service Implementation
The service implements a listener that listens to the requests sent. This is done by implementing and registering a class that implements SoapReceiver.
The SoapService listens for requests. Once a request comes The request is processed asynchronously and when the response is ready, the response is posted back to the client using the ReplyTo address found in the original SOAP Request message.
SoapEnvelope retEnv = new SoapEnvelope();
retEnv.Context.Addressing.To = new To(epDestination.Address);
retEnv.Context.Addressing.Action = new Action(respEnv);
SoapSender ssend = new SoapSender(epDestination);
To correlate the response from the service to the request sent, a ReferenceProperty can be added to the ReplyTo address EndPointReference as follows:
epDestination.ReferenceProperties =new ReferenceProperties();
corElement = corDoc.CreateElement("corId","CorrelationId",
In the response, send the correlation ID by parsing the Reference property of the ReplyTo address End point Reference as follows:
if (envelope.Context.Addressing.ReplyTo.ReferenceProperties != null)
corElement = envelope.Context.Addressing.ReplyTo.
corElement = (XmlElement)corElement.
Populate the RelatesTo field of the response message with this correlation ID. In the client, get the correlation ID by parsing the RelatesTo field of the response message:
corElement = envelope.Context.Addressing.RelatesTo.GetXml(corDoc);
You have essentially seen a way to communicate seamlessly between a client and a server Application by taking advantage of WSE 2.0 using HTTP that is supported by all systems. I wish to thank Nizam Mohideen, my manager, for his help in composing this article.