Using the Client Proxy and the Client Implementation
We use the client proxy to implement the HelloWorld client application. The generated sample implementations by default use one of the proxy’s synchronous methods, as shown here:
 
void invoke_sayHello(GreetingBindingProxy& proxy)
This section discusses implementing the client for a synchronous operation. For information on asynchronous operations, see Chapter 13, Asynchronous Messaging.
The following code shows the provided client implementation file, <installdir>\examples\HelloWorld\GreetingPortClient.cpp. The client implementation is not a class, but rather a source file that includes the proxy header file and a main() function that invokes the proxy’s methods. The code below is reformatted slightly to fit on the page:
#include "HelloWorldExample/GreetingBindingProxy.h" //1
#include <iostream>
 
#include <rwsf/webservice/DefaultLogger.h>
#include <rwsf/webservice/HandlerManager.h>
#include <rwsf/webservice/MessageHandler.h>
#include <rwsf/webservice/transport/TransportManager.h>
 
void invoke_sayHello(GreetingBindingProxy& proxy) //2
{
std::string hellorequest_in("World!");
std::string return_ret;
rwsf::CallInfo callInfo;
 
try {
return_ret = proxy.sayHello(callInfo, hellorequest_in);
std::cout << "Server Response: " << return_ret << std::endl;
} catch(const rwsf::SoapFaultException& e) {
std::cout << "Fault Code: " << e.getFault().getFaultcode().asString()
<< std::endl;
std::cout << "Fault String: " << e.getFault().getFaultstring()
<< std::endl;
}
}
 
void logError(std::string error, std::string detail) {
rwsf::HandlerManager::invokeLogger(error + ": " + detail,
rwsf::CallInfo::Error);
}
 
using rwsf::DefaultLogger;
RWSF_DEFINE_STATIC_MESSAGE_HANDLER("RWSFClientLogger", DefaultLogger)
 
int main(int argc, char* argv[])
{
// Instantiate GreetingBindingProxy.
// If you need to override the URL given in the WSDL file for
// the service, modify the constructor argument or pass in on
// the command line
 
std::string location; //3
 
if (argc < 2) {
location = "http://localhost:8090/helloworld/HelloWorld";
}
else if (argv[1][0]=='-' && argv[1][1]=='a') {
location = "http://localhost:8013/helloworld/HelloWorld";
}
else if (argv[1][0]=='-' && argv[1][1]=='l') {
location = "http://localhost:8090/helloworld/HelloWorld";
}
else {
location = argv[1];
}
 
try {
// initialize config files
try {
// default path from the bin directory
rwsf::NamingContext::loadGlobal("../conf/client-objects.xml");
rwsf::HandlerManager::loadConfiguration("../conf/client-handlers.xml");
rwsf::TransportManager::initialize("../conf/client-transports.xml"); //4
}
catch(...) {
// default path from the app/client vcproj file
rwsf::NamingContext::loadGlobal("../../conf/client-objects.xml");
rwsf::HandlerManager::loadConfiguration("../../conf/client-handlers.xml");
rwsf::TransportManager::initialize("../../conf/client-transports.xml");
}
 
GreetingBindingProxy proxy = GreetingBindingProxy::make(location); //5
 
if(!proxy.isValid()) {
std::cerr << "Unable to create proxy. " << "\nExiting" << std::endl;
return 1;
}
 
invoke_sayHello(proxy); //6
 
}
catch (const rwsf::Exception& x) { //7
logError("rwsf::Exception thrown", x.what());
std::cerr << "rwsf::Exception thrown: "
<< x.what() << std::endl;
return 1;
}
catch(const std::exception& x) {
logError("std::exception thrown", x.what());
std::cerr << "std::exception thrown:" << std::endl
<< x.what() << std::endl;
return 1;
}
catch(...) {
logError("Unknown exception thrown", "");
std::cerr << "Unknown exception thrown" << std::endl;
return 1;
}
return 0;
}
//1 Include necessary header files.
//2 Function that invokes the sayHello() operation. The function takes a reference to a GreetingBindingProxy, creates a standard string “World!” and an empty standard string instance, and calls the sayHello operation on the proxy.
The client implements one sample invocation method that takes an explicit rwsf::CallInfo parameter. The program provides a try block around the code that calls methods on the proxy. The proxy indicates errors by throwing a rwsf::SoapFaultException derived from rwsf::SoapFault, and the server writes a log message by default. Note that the generator makes no attempt to provide valid input for the operation.
//3 The main() function first determines the location for the service through a combination of information from the WSDL and possible command line options and arguments.
If no command line argument is used when invoking the client, the default is the location specified in the WSDL.
//4 Registers the service handlers and transports that are available for this message.
//5 Obtains a client proxy and ensures that it is valid.
//6 Calls the invoke_sayHello() method on the proxy.
//7 Catch blocks for exceptions that might be thrown by this call. The exceptions shown should always be caught. If you generate code with the ‑SourcePro option, which uses Rogue Wave SourcePro C++ datatypes, then you should also catch exceptions derived from RWxmsg.
The sayHello operation requires a string as input (“World!”) and returns a message containing an string with the value “Hello World!”
The next step is to develop the service implementation. Then we’ll compile and run the application.