The implementation of this service takes place in three files:
WeatherSummaryImp.cpp. A server-side class containing implementations of the getSummary() and updateWeather() service operation methods, the call to the weatherNotification() notification operation method in the server-side notification proxy, as well as the call to the server-side solicit-response operation weatherStatusRenew(), also a call to the server-side proxy.
WeatherSummaryClient.cpp. A client-side main() function that contains the calls to the getSummary() and updateWeather() service operation methods in the client proxy.
WeatherSummaryNotificationImp.h and WeatherSummaryNotificationImp.cpp. Contains the client-side implementation of the weatherNotification() service operation method, and the client-side response
The WeatherSummary example ships with implemented versions of these files, located in the example directory along with the WeatherSummary.wsdl. The discussions that follow are based on these provided implementations.
The code below is an excerpt from WeatherSummaryImp.cpp. It shows the message handler registration macro and the request-response operation method getSummary().
RWSF_DEFINE_MESSAGE_HANDLER(WeatherSummaryImp) // Request-Response operation method wsx::WeatherSummary WeatherSummaryImp::getSummary(rwsf::CallInfo& callInfo, const std::string& zipcode_in) { wsx::WeatherSummary ws; //1 ws.setSky("clear"); //2 ws.setTemp(72); ws.setWindSpeed(5); ws.setZipcode(zipcode_in); return ws; //3 }
//1 | Create a WeatherSummary object. |
//2 | Populate the object with some made-up data, except for the zip code, which is taken from the request. The C++ data binding created for the WeatherSummary XML element contains accessor and mutator methods for obtaining and modifying the data for any sub-elements of WeatherSummary. |
//3 | Return the object, which gets translated into a SOAP message and sent back to the client.
|
One extra class is generated on the server side to support the notification pattern. The class WeatherSummaryNotificationProxy is a generated proxy used to send a message to the client.
This file is very similar to the generated proxy on the client side, containing both asynchronous and synchronous service operation methods that can be used by the client. Here is a brief excerpt:
class WeatherSummaryNotificationProxyImp : public rwsf::ClientImp { //1 public: WeatherSummaryNotificationProxyImp(const rwsf::Transport& transport); virtual ~WeatherSummaryNotificationProxyImp(); void setTransportProperty(const std::string& property, const //2 std::string& value); // synchronous operations //3 virtual void weatherNotification(rwsf::CallInfo& info, const wsx::WeatherSummary& weatherData_in); // async operations virtual rwsf::AsyncHandle weatherNotificationStart(rwsf::CallInfo& info, const wsx::WeatherSummary& weatherData_in); virtual void weatherNotificationEnd(rwsf::AsyncHandle& handle);
//1 | Derives from rwsf::ClientImp, as does the proxy on the client side. |
//2 | Sets the transport. |
//3 | Contains asynchronous or synchronous service operation methods. |
Let's first look at an excerpt from WeatherSummaryImp.cpp showing the implementation for the one-way operation method updateWeather(). This implementation does not really do anything with the weather update, but uses the message's arrival as the event that triggers a call to the notification operation method weatherNotification() in the special-generated class WeatherSummaryNotificationProxy.
// One-way operation method void WeatherSummaryImp::updateWeather(rwsf::CallInfo& callInfo, const std::string& host_in, const std::string& port_in, const std::string& transportName_in, const wsx::WeatherSummary& weatherData_in) { // In a fully implemented service, this weather update // would be persisted in some way, keyed to the the zip // code that is part of the WeatherSummary object. // Then a list of zip codes wanting notification of this // update would be iterated through and a notification // sent to each ... std::string location; //1 if (transportName_in == "HTTP") { //2 location = "http://"; } else if(transportName_in == "HTTPS") { location = "https://"; } WeatherSummaryNotificationProxy notifProxy; if (location.length()) { //3 location+= host_in; std::string port = port_in; if (port.length()) { location += ":"; location += port; } notifProxy = WeatherSummaryNotificationProxy::make (rwsf::createrwsfString(location)); //4 } else { //5 rwsf::Transport t = rwsf::TransportManager::findTransport (rwsf::createrwsfString(transportName_in)); notifProxy = WeatherSummaryNotificationProxy::make(t); //6 } notifProxy.weatherNotification(callInfo, weatherData_in);} //7
//1 | Creates an string object to hold the location for the service. |
//2 | Tests whether the transportName_in parameter equals HTTP or HTTPS. If so, the location string is set to the appropriate scheme, http:// or https://. |
//3 | If the scheme was set, uses the host_in and port_in parameters to construct a complete URL for the location.
In a real service, this would be supplied by the target client as part of a subscribe operation and would be a URL available across the Internet. For this example, the location to be used is based on the listener created in the client implementation (see below). |
//4 | If the location string is unempty, creates an instance of the proxy by passing the location as a parameter. |
//5 | The path that is followed if transportName_in is other than HTTP or HTTPS. |
//6 | Creates an instance of the proxy by passing the transport name as a parameter. |
//7 | Uses the weather update that has just arrived as the data sent in the notification message. |
Once the notification message has been sent, the server immediately sends a solicit-response method, to see if the client wishes to renew receipt of weather updates. Obviously, in a real service, a different event would trigger the server's solicit message to renew.
The following code in WeatherSummaryImp.cpp shows the solicit-response service operation method.
... std::string renewal = std::string("Your subscription has expired. Do you want to renew?"); //1 notifProxy.weatherUpdateRenew(callInfo, renewal); //2 ...
//1 | Creates a string renewal with the solicit message. |
//2 | Sends the renewal string as part of the solicit-response service operation method weatherUpdateRenew(). |
© Copyright Rogue Wave Software, Inc. All Rights Reserved. All Rights Reserved. Rogue Wave is a registered trademark of Rogue Wave Software, Inc. in the United States and other countries. HydraExpress is a trademark of Rogue Wave Software, Inc. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.