Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
HydraExpress User Guide

5.3 Creating a Custom Connector

To create a custom connector, you need to:

  1. Derive a new class from rwsf::ConnectorImp

  2. Implement a method for handling requests, and some kind of threading framework for the connector to run in.

  3. Override the pure virtual methods init(), start(), and stop().

  4. Configure the connector.

The following sections present code showing how to create a socket connector. Most of the code is pseudo code that will not compile without some additional elements.

5.3.1 Request Handling and Threading

This is the code to create a custom connector class:

//1

The rwsf::Config class holds properties passed to the connector. For more information on the data and methods available through this class, see its class description in the HydraExpress C++ API Reference Guide.

//2

The rwsf::AgentContext class provides access to Agent resources.

If you are most interested in learning more about the virtual method implementations for init(), start() and stop(), skip to Section 5.3.2. The remainder of this section discusses the message handling aspects of the connector.

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

//1

Create a socket thread based on the supplied socket.

//2

Call the run() method to activate the connector.

//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 connector needs to do the following work:

This sample code declares the RequestHandler class:

Here is the implementation for the run() method that actually processes the request:

//1

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

//2

Sets the payload into the rwsf:request:payload data structure of an rwsf::MessageInfo instance. See the table at the end of this section.

//3

Obtains the handler chain configured for this connector (see an example below).

//4

Dispatches the message to the handler chain.

//5

Obtains the response payload data structure.

//6

Writes the response message to the socket.

When the invoke has completed, the rwsf::MessageInfo 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 connector instance.

RWSF_DEFINE_CONNECTOR(MyConnector);

The following table shows some of the main data structures in rwsf::MessageInfo.

Table 9: Data structures in rwsf::MessageInfo

Name Type Description
rwsf/request/payload std::string The request payload of this message.
rwsf/response/payload std::string The response payload of this message.
rwsf/response/transport/headers rwsf::MimeHeaders Data specific to transport headers.

5.3.2 Implementing the Virtual Methods

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

The derived init() method should invoke the init() method of its parent so the parent class can also process any information from the rwsf::Config instance.

The start() method 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 Agent invokes the start() method after it has initialized all connectors and handlers.

The stop() method should be implemented as a blocking call. The stop() method first releases any resources the connector owns and then stops the connector. The Agent invokes the stop() method when the Agent receives a signal to shut down.

5.3.3 Configuring the Connector

Compile your new connector into a shared library (DLL) and place it in the bin directory of your HydraExpress installation. You are now set to load the connector into the Agent. You do this by creating a new rwsf:connector element in rwagent.xml with the appropriate configuration information. For example:

The name attribute is the string that represents the connector to the rest of the system. This string must be unique in the system.

The class attribute defines how to create an instance of this connector. In this example, myconnector is the name of the shared library that contains the connector code. The string createMyConnector is the name of the method that was created from the RWSF_DEFINE_CONNECTOR macro described above.

The handlerChain attribute specifies the name of the handler chain that this connector is tied to. The handler chain must be declared in rwagent.xml before the connector is declared. The example uses the handler chain that the HTTP/1.1 connector is using.



Previous fileTop of DocumentContentsNo linkNext 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.
Provide feedback to Rogue Wave about its documentation.