Selectable Transports and Listeners
The transports and listeners defined in the transport configuration files are all identified by a name. At runtime, either the client or the server (when sending notifications or solicit messages) can select by name the transport to be used to send a message.
Let’s consider the following scenario:
*The clients for a service send one-way messages via HTTP requesting quotes for the items in a purchase order.
*The service parses the purchase order and develops a quote based on the items in the purchase order. The service then sends a notification message with the quote back to the requestor using HTTP or email, depending on the client’s preference.
Let’s suppose that the name of this service is GetQuotes and that it is provided by a company called A2Z Incorporated. The code below shows the code in the client implementation that sends off a purchase order for quotation.
void invoke_sendForQuote(GetQuotesProxy& proxy, std::string location)
PurchaseOrder po = getPurchaseOrder("A2Z Incorporated"); //1
rwsf::CallInfo callInfo;
proxy.sendForQuote(callInfo, po, location); //2
int main(int argc, char* argv[]) {
if( argc < 3 ) {
printf("Usage: %s [request url] [email address | url]\n", argv[0]); //3
return 0;
std::string serivceURL(argv[1]);
std::string location(argv[2]);
rwsf::Transport transport;
rwsf::Transport transport = //4
GetQuotesProxy proxy = GetQuotesProxy::make(transport); //5
invoke_sendForQuote(proxy, location); //6
//1 Calls some method that creates a PurchaseOrder object from the items that need to be ordered from the company named in the parameter.
//2 Invokes the client proxy sendForQuote() one-way operation method, passing in the location to send the quote to, either an email address or a URL.
//3 If the correct number of arguments (two) is not provided, prints “Usage...”
//4 Gets the transport to use for sending the request, based on the URL.
//5 Creates a proxy with the specified transport, used for sending a purchase order to the location for the A2Z incorporated server.
//6 Invokes the service operation method for sending a purchase order for quote.
On the server side, the implementation evaluates how to send the notification, based on the location:
void GetQuotesImp::sendForQuote(rwsf::CallInfo& callinfo,
const PurchaseOrder& po,
std::string location)
Quote quote = provideQuote(po); //1
rwsf::Transport transport;
If( isEmailAddress(location) ) { //2
transport = rwsf::TransportManager::findTransport(“SMTP”);
transport.setProperty(“email-address”, email); //3
transport = rwsf::TransportManager::findTransportByUrl(location); //4
GetQuotesNotificationProxy proxy =
GetQuotesNotificationProxy::make(transport); //5
proxy.reply(callInfo, quote); //6
//1 Sends the incoming purchase order to a method that returns a quote.
//2 If the location provided is an email address, creates a transport object that sends messages by SMTP, which must be a named transport defined in the transports.xml configuration file.
//3 Sets the email transport email-address property to the email address of the company requesting the quote.
//4 Otherwise, creates a transport based on the provided URL location.
//5 Obtains a proxy based on the selected transport.
//6 Returns the quote via email.
This example has shown how to select between two possible transports at runtime, from both the client and server. Next let’s consider how to change the type of a named transport by altering the configuration file and thereby avoiding any changes to the code that would require recompiling.