Standalone Server Implementations
HydraExpress supports service deployment independent from the Agent. To take advantage of this feature, use the -standalone option when generating code in order to generate a sample standalone server.
For example, this invocation of the code generator for the DayOfWeek example
<prompt>rwsfgen -standalone example-project.xml
generates a sample server implementation, DayOfWeekPortServer.cpp in the app\server directory.
The generated sample shows how you could incorporate a HydraExpress service in your application directly, rather than through the Agent. As a result, certain features provided by the Agent are not supported, including multithreading, load balancing, and sessions. However, all the message processing capabilities are present.
The sample server implementation contains a simple main() that loads and initializes named objects, handlers, transports, and listeners, and then starts the listener.
To use the standalone sample server:
1. Configure the listener and other loadable components in the usual way, using their configuration files. The listener’s configuration file is transports.xml.
2. Build your service as usual.
3. Make sure the service library can be found and loaded by the operating system. If needed, you can deploy your service as usual (using deploy target of the generated makefile), or add the service library path to the appropriate system environment path.
4. Start the server by launching its executable and passing the name of the listener as a command line argument.
NOTE >> Note: Start the server from your project directory, rather than directly in <projectdir>\bin. This ensures that the server can locate the necessary configuration files at startup.
For example, to use a secure listener, change to your project directory, and enter:
Windows: <prompt> bin\DayOfWeekPortServer.exe -t HTTPS
UNIX/Linux: <prompt> ./bin/DayOfWeekPortServer -t HTTPS
If no listener is specified, the HTTP listener is started by default.
5. Run your client by opening another command window, and invoking the client. For HTTP and HTTPS, run the client with the appropriate URL as the command line argument. Note that in the URL, you need to use the port on which the standalone server is listening, as defined in transports.xml.
Standalone Server Options
The standalone server takes two runtime options:
• -t <transport>
The name of the transport to use. The default is HTTP.
• -c <conf_directory>
The path to the directory containing the configuration files. The default is the <project-directory>\conf directory. This option makes it easy to move and start the server from any location.
Standalone Server Ports
The standalone server uses the following default ports:
9090 | Used for HTTP requests |
9443 | Used for HTTPS requests. |
For example:
DayOfWeekPortClient https://localhost:9443/dayofweek/DayOfWeek
Shutting down a Standalone Server
HydraExpress supports shutting down a service from within the service implementation through class
rwsf::ServiceShutdownException.
In the case of HTTP and HTTPS transports, for any request that results in this server exception, the server sends a 500 “Internal Server Error” response back. For a standalone HTTP or HTTPS server, the listener shuts down and subsequent requests fail. The thread that contains the listener object can then call the method isStopped() to see if has been shut down.
For more information, see the class description for
rwsf::ServiceShutdownException.
About Configuring a Multithreaded Standalone Server or Listener
To configure a multithreaded standalone server, you need to add properties to the transport configuration file
transports.xml. To configure a multithreaded standalone listener in the event that you are using the message pattern notification, add properties instead to the client-side transport configuration file,
client-transports.xml. See
Table 15 for details on these properties.
Table 15 – Multithreaded standalone server and listener properties
Property name | Value | Description |
accepter-threads | int | Specifies the number of threads that should be spawned listening for new connections. Defaults to 1. |
thread-pool-min | int | The minimum number of threads to be created in the thread pool. Defaults to 0. |
thread-pool-max | int | The maximum number of threads to be created in the thread pool. Defaults to 0.1 |
To implement a multithreaded standalone server, you must specify a non-default value for the accepter-thread property or for the thread pool properties; otherwise, only one thread is created to accept incoming requests.
To ensure that incoming connections are handled correctly, we recommend that you do set values for the two thread pool properties in order to implement a thread pool. In this way, the accepter threads accept the connection, pass it off to the thread pool, and then go back to accepting connections. The thread pool then queues the request, ensuring that any client trying to connect will actually get through.
Without a thread pool, the accepter threads do the actual work, potentially “starving” incoming connections if no threads are available. Most importantly, using accepter threads without a thread pool can result in a Denial of Service attack if incoming messages open connections to all of your accepter threads, and then send small requests that keep them open indefinitely.
To configure your multithreaded server, add the following lines to the listener you will use in transports.xml, or in client-transports.xml if you are using the message pattern notification:
<rwsf:listener name="HTTP"
...
<rwsf:property name="host" value="localhost"/>
<rwsf:property name="port" value="9090"/> -->
<rwsf:property name="accepter-threads" value="2"/>
<rwsf:property name="thread-pool-min" value="5"/>
<rwsf:property name="thread-pool-max" value="20"/>
...
</rwsf:listener>