Advanced features

  1. adjusting maximum of concurrent read/process/write operations
  2. using compression
  3. choosing between blocking and non-blocking IO
  4. using remote classloading
  5. firewall issues: how to use packaging of requests and responses within HTTP POST and RESPONSE containers

Adjusting maximum of concurrent read/process/write operations

EJOE strictly differentiates between two kinds of threads:

  • combined Read/Process threads
  • Writer threads
The main burden on serverside is handled within the combined read/process threads because they handle data receiving as well as executing your ServerHandler implementation.

Writer threads are used for sending data from the EJOE server to the clients only.

Per default EJOE uses 4 concurrent read/process threads and 2 concurrent writer threads.

If you expect hundreds or thousands of concurrent client connection you HAVE to adjust these settings to get an acceptable server throughput.

It is a recommended rough rule of thumb to use a lesser amount of writer threads than read/process threads.

To adjust the values used for the maximum of these two kinds of threads use the following two methods the EJServer class does provide:

ejserver.setMaxReadProcessors( int maxProcessors )
and
ejserver.setMaxWriteProcessors( int maxProcessors )

Using compression

EJOE does support compression of the used datastreams. This can be a helpful feature especially when dealing with large (text-based) data eg. big XML documents.

Compression is a so called "selective feature" in EJOE. It means that a client can request compression but it will be used only if support for compression enabled in the EJOE server. Use the following line of code to enable compression in the server:

ejserver.enableCompression();
Be aware that you have to enable that feature before starting the server.

On clientside you can enable/disable compression for each call or when you think that compression might be useful for the sent data or the expected answer by the server. Use the following line of code to enable compression in the client:

ejclient.enableCompression(true);

Choosing between blocking and non-blocking IO

Since version 0.3.4 EJOE uses non-blocking I/O as default I/O mechanism. If you are dealing with large objects it could be an option to disable non-blocking I/O so that (de)serializing can be done directly using blocking io streams without buffering the objects completely within ByteBuffer objects. This *can* be a significantly improvement because tests have shown that the direct invoking of the (de)serialize adapters:

  1. setting the accepted socket connection to blocking mode
  2. open an InputStream directly on the socket
  3. hand over the InputStream to the (de)serialize adapter
can be much faster with large data than the non-blocking aproach:

  1. receive data the non-blocking way, have to read them into a buffer
  2. create an InputStream on the buffer
  3. hand over the InputStream to the (de)serialize adapter
To disable non-blocking I/O use the following line of code:

ejserver.enableNonBlockingIO( false );
The good news: The clients will handle the used I/O mechanism automatically.

remote classloading

EJOE contains support for remote classloading. Remote classloading is usually a neccessary feature if your server side returns object type, eg. custom beans, which are not included in the classpath on the clientside. EJOE is not able to deserialize such custom types without remote classloading in such cases. For remote classloading a custom classloader (de.netseeker.ejoe.EJClassLoader) is used. That classloader basically uses the same mechanism as EJClient to retrieve class informations from the server:

To enable remote classloading you must first enable remote classloading in EJServer:
EJServer myServer = ...;
myServer.enableRemoteClassLoading(true);
Then you must tell the EJClient to use the remote classloading of the EJServer:
EJClient myClient = ...;
myClient.enableRemoteClassloading(true);
You can also provide a file called ejoe.properties on the client's classpath with:
ejoe.remoteClassloader = true //default is false
and use the default constructor:
	EJClient()
Be aware that EJClient will change the context classloader of the tread in which the client runs. Usually this is not a problem because the EJClassLoader delegates first to the former context classloader...

HTTP packaging

HTTP packaging means encapsulating of request data within HTTP POST request and sending the reply back to clients as HTTP-encapsulated data. This can be very useful if a client is behind a firewall. Hint: HTTP packaging is available for non-blocking I/O only! To use HTTP packaging you have to enable the feature on both sides: EJServer and EJClient. If it is enabled in the server, the server will still be able to process non-HTTP requests. Enabling HTTP-packaging in EJServer:
EJServer server = new EJServer( ... );
server.enableHttpPackaging( true );
Or if you use a configuration file (usually ejserver.properties):
...
ejoe.httpTunneling=true
...
Enabling HTTP-packaging in EJClient:
EJClient myClient = new EJClient(...);
myClient.enableHttpPackaging( true );
Or if you use a configuration file (usually ejoe.properties):
...
ejoe.httpTunneling=true
...