Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
HydraExpress Web Service Development Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

11.7 Creating a Listener

All custom listeners derive from the class rwsf::MessageListenerImp.

To create a custom Listener:

  1. As with transports, extend this class and implement at least these five pure virtual functions:

      virtual void doInit(const rwsf::Config& initParams) = 0;
      virtual void initServer() = 0;
      virtual void doStart() = 0;
      virtual void doStop() = 0;
      virtual void doReset() = 0;
      
  2. Implement a method for handling requests, and some kind of threading framework for the listener to run in.

  3. Define the macro RWSF_DEFINE_MESSAGE_HANDLER(NAME) in the implementation file.

  4. Configure the listener in the configuration file client-transports.xml.

Section 11.7.1 discusses code for handling incoming messages and creating the threading mechanism. For specifics on implementing the five virtual functions, see Section 11.7.2.

11.7.1 Request Handling and Threading

This code creates a custom listener class:

//1

The rwsf::Config class holds initialization parameters passed to the listener from the listener configuration file, client-transports.xml. For more information on the data and methods available through this class, see its class description in the HydraExpress C++ API Reference Guide.

//2

Note that client_ and SocketThread are not HydraExpress classes but are just used for illustration purposes in this example.


For threading and network capabilities in HydraExpress services, you can use the network and threading classes of Rogue Wave's SourcePro.

The following lines are pseudo code for creating a threading framework. This framework is needed so the doStart() method can be implemented as non-blocking.

//1

Create a socket thread based on the supplied socket.

//2

Define the main listener thread.

//3

The run() method must test some condition that lets it know when to return.

//4

The socket accepts the message off the line and stores it in some kind of object.

//5

The message off the socket is executed in a RequestHandler thread. The start() method starts the thread and then calls the run() method of RequestHandler. See below for a pseudo code implementation of this class.

A listener needs to do the following work:

This sample code declares the RequestHandler class:

The RequestHandler's run() method invokes the listener's handleRequest() method, which actually processes the request:

//1

Reads the data taken off the line by the socket into a string.

//2

Sets the request payload on an rwsf::CallInfo object.

//3

Invokes the service implementation.

//4

Gets the response from the rwsf::CallInfo object.

//5

Writes the response message to the socket.

When the invoke has completed, the rwsf::CallInfo should contain any information needed to send back a response. This information might include a response payload, headers, a status code, and so on. You need to implement code for writing that information to a location where the client can retrieve it.

Finally, use the following convenience macro that generates code to create a listener instance.

11.7.2 Implementing the Virtual Methods

The following code shows the init() method for a listener that watches a directory. The init() method is called during Agent initialization, and the name of the directory is passed to the listener in an rwsf::Config instance.

These are the implemented virtual functions:

The doInit() method initializes the listener based on initialization values it gets from the rwsf::Config instance.

The initServer() method needs to perform any setup needed by the listener before it is started. In the example below, note that the Socket class is for illustration only; it is not a HydraExpress class.

The method doStart() kicks off the thread to start the listener. It should be implemented as a non-blocking method, and should prepare the system that waits for events and accepts requests for the rest of the system. In most cases, the start() method spawns at least one thread that listens for requests.

The method doStop() shuts down the thread, stopping the listener. The stop() method first releases any resources the listener owns and then stops the listener.

Use doReset() to reset the listener to the state it was in before it started.

11.7.3 Configuring the Listener

Compile your new listener into a shared library (DLL) and place it in the bin (Windows) or lib (UNIX/Linux) directory of your HydraExpress installation. You are now set to load the listener into the Agent.

The client must have access to this listener's configuration in the file client-transports.xml, as discussed in Section 11.2 and Section 11.3. On the server side, the listener is configured in the transports.xml file deployed with the service for use by HydraExpress services.

For an example of how to use a listener from client code, see Section 11.4, "Using an Autoconfigured Listener." While that section discusses using a provided default HTTP listener, any custom listener could also be loaded from client code in this same way.



Previous fileTop of DocumentContentsIndex pageNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo are registered trademarks of Rogue Wave Software, and HydraExpress is a trademark of Rogue Wave Software. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.