Message Patterns in WSDL
HydraExpress determines the message pattern for a given operation by evaluating the pattern of input and output messages for the operation in the service WSDL file. Based on this analysis, it generates code appropriate to the message patterns being used.
This section discusses each message pattern, with an introduction to the WeatherSummary.wsdl that is used for illustration. It also includes a brief discussion on synchronous and asynchronous behavior as it relates to message patterns.
Weather Summary Service Description
The Weather Summary service represents a centralized provider of weather condition data for some number of subscribers in some area.
• A client subscribes (or unsubscribes) to receive area weather data, and receives a confirmation from the server. This interaction represents a request-response operation.
• Subscribers can choose to send weather data to the service when local conditions change, using the one-way operation.
• The service sends notifications of changed conditions to all subscribers through the notification operation.
• Finally, when the service receives a subscription request, it uses the solicit-response operation for verify that the requesting client is reachable, using the result to determine whether the subscription request succeeds.
The Request-Response Pattern
The request-response operation includes one input element, which is the client’s request to the server, followed by one output element, which is the server’s response back to the client.
In WeatherSummary.wsdl, the request-response operation is defined by the subscribe and unsubscribe operations:
...
<operation name="subscribe">
<input message="tns:subscribe"/>
<output message="tns:subscribeResponse"/>
</operation>
<operation name="unsubscribe">
<input message="tns:subscribe"/>
<output message="tns:subscribeResponse"/>
</operation>
...
The operation subscribe contains an input message subscribe, which is the client request, and an output message subscribeResponse, which is the server response. The contents of these messages are then defined in the WSDL file’s message element:
<message name="subscribe">
<part name="host" type="xsd:string"/>
<part name="port" type="xsd:string"/>
<part name="transportName" type="xsd:string"/>
</message>
<message name="subscribeResponse">
<part name="status" type="xsd:boolean"/>
<part name="message" type="xsd:string"/>
</message>
The message subscribe contains three parts of type xsd:string that tell the service where and how to send messages.
The message subscribeResponse contains two parts, a status of type xsd:boolean indicating success or failure of the request, and a message string.
The implementation of this pattern occurs in the client-side WeatherSummaryClient.cpp, a sample implementation that uses the generated class in WeatherSummaryProxy.cpp, and in the server-side WeatherSummaryImp.cpp, the server implementation that receives the request and sends a response.
For more information on the request-response pattern, see the examples discussed in Part I, “Getting Started,” as well as those in
Part IV, “Extending your Applications.”The One Way Pattern
The one-way operation includes one input element, which is the client’s request to the server. No response is expected.
In WeatherSummary.wsdl, the one-way pattern is defined by the operation weatherUpdate:
<!-- One-way -->
<operation name="weatherUpdate">
<input message="tns:weatherUpdate"/>
</operation>
The operation weatherUpdate consists of one input message containing several parts.
<message name="weatherUpdate">
<part name="weatherData" type="wsx:WeatherSummary"/>
</message>
The message contains a complex type
WeatherSummary element that provides updated weather conditions for the local area. The
WeatherSummary type is defined by an embedded XML Schema in the
types element of the WSDL file. See
“Complex Data.”The implementation of this pattern occurs in the client-side WeatherSummaryClient.cpp, a sample implementation that uses the generated class in WeatherSummaryProxy.cpp, and in the server-side WeatherSummaryImp.cpp, the server implementation that receives the request.
The Notification Pattern
The notification operation includes one output element, which is the server’s message to the client.
In WeatherSummary.wsdl, the notification pattern is defined by the operation weatherNotification:
<!-- Notification -->
<operation name="weatherNotification">
<output message="tns:weatherNotification"/>
</operation>
The operation consists of one output message from the server to one or more clients.
<message name="weatherNotification">
<part name="weatherData" type="wsx:WeatherSummary"/>
</message>
The message contains a WeatherSummary element with updated weather conditions for the zip code specified in the WeatherSummary element.
HydraExpress uses special notification architecture to support this pattern. This architecture is described in
Chapter 13 .
This pattern is implemented on the server side by WeatherSummaryImp.cpp, which makes a call to the weatherNotification() operation method in the server-side notification proxy WeatherSummaryNotificationProxy.cpp, and on the client side in WeatherSummaryNotificationImp.cpp, which sets up a listener on the client to receive the notification.
For an additional examples on the notification pattern, see
Chapter 10 .
The Solicit-Response Pattern
The solicit-response operation includes one output element, which is the server’s request to the client, followed by one input element, which is the client’s response back to the server.
In WeatherSummary.wsdl, the solicit-response pattern is defined in the operation verifySubscription.
<!-- Solicit-response -->
<operation name="verifySubscription">
<output message="tns:verifySubscription"/>
<input message="tns:verifySubscriptionResponse"/>
</operation>
This operation consists of one output message verifySubscription and one input message verifySubscriptionResponse defined below.
<message name="verifySubscription">
</message>
This is the request message from the server to the client used to verify that the client exists and is reachable. There is no message content since the nature of the request requires no data.
<message name="verifySubscriptionResponse">
<part name="status" type="xsd:boolean"/>
</message>
This is the response message from the client back to the server. If the request reaches the client, it simply responds with a boolean true. Otherwise, the server receives some kind of error and knows that the client could not be reached.
This pattern requires the server to initiate a message and the client to receive one, so it uses the notification architecture to support this pattern. This architecture is described in
“Architecture of the Notification Classes.”This operation is implemented on the server side in WeatherSummaryImp.cpp, which makes the call to the notification proxy in WeatherSummaryNotificationProxy.cpp to send the verification request to the client. On the client side, the client implementation WeatherSummaryClient.cpp sets up a listener and a notification class, implemented in WeatherSummaryNotificationImp.cpp, receives the notification message.
Message Patterns and Asynchronous Messaging
The request-response and the solicit-response patterns are generally synchronous, as their usage usually assumes that the requestor will receive an immediate response.
The one-way and the notification patterns are inherently asynchronous in that the requestor expects no response.
While one of the strengths of WSDL is that it allows any mix of message patterns and transports in a single service, it is important to be aware that the behavior of a service is tied to the type of transport being used. For example, an asynchronous service will not behave asynchronously if it is sent using a synchronous transport, such as HTTP. This is because HTTP requires a response as a receipt. Even if the C++ function calling the web service is multithreaded and returns before the response is received, the transport itself must block until the HTTP response is received. This becomes important if multiple messages are sent over the same channel.
For this reason, it may be wise to build one-way and notification messages asynchronously to avoid having the client block for a transport receipt. In addition, using the asynchronous methods for one-way and notification builds more responsiveness and adaptability into your program without much more complication.
For a general discussion on building services asynchronously, see
Chapter 13 .