The heart of Net4j is a fast and scalable, Java NIO-based buffer switching technology which is completely non-blocking and allows for multiple levels of buffer multiplexing. On top of this buffer-oriented transport layer there is an optional stream-oriented protocol layer which is used to implement application protocols. The framework automatically ensures that multiple such protocols can be multiplexed through a single physical transport connection like a TCP socket and that the transport type can be transparently changed to other mediums like HTTP or JVM.
I think the idea behind Net4j becomes clearer when we look at an example. Let's develop a small protocol to upload files to a remote server with full support of IProgressMonitor over the network. In Net4j this is a single signal (aka communications use-case) of a protocol and we need to provide implementations for both sides of the protocol. We start with the client-side request implementation.
Now the application can create instances of this request and call the send() method on them. The framework in turn calls the requesting() and confirming() methods when the transport layer is able to handle the data. The following example method encapsulates the sending process. Notice how the IProgressMonitor is converted to an OMMonitor.
This simple method can now be used in a workbench action. The transferFile() call is wrapped in a Job to make it run in a background thread and to integrate with the Eclipse Progress view.
The complete source code of this action class is available via CVS. Now we only need a server that is able to receive and handle our request. We start with the server-side request implementation (called an indication).
When the data of an UploadRequest arrives atthe server the Net4j framework creates an instance of our UploadIndication and calls the indicating() and confirming() methods appropriately. Therefor we need to register a signal factory, i.e. a customized protocol. In our case we create the protocol instance on-the-fly inside of the protocol factory.
If the server was expected to run in OSGi/Equinox the only missing thing would be the contribution of this protocol factory to an extension point.
But we want to look at a simple stand-alone version of our upload server.
The complete source code of the server class is available via CVS. To enhance the maintainability of our upload protocol some protocol constants are defined in a common interface. This makes it particularly easier to add new signals.
Now we just need to start the server and watch the console.
And finally we start a runtime Eclipse application with our UploadClientAction deployed. When you click this action a file selection dialog is displayed. The chosen file will be uploaded to the server and stored there in a temp folder. The progress of the upload operation is properly reflected in the Eclipse Progress view and can even be cancelled at any point in time.
This is only one example of the many things you can do with Net4j. Please note that the actual client/server communication in Net4j has some characteristics that differ from other remoting technologies, among them:
- There are no discrete marshalling/un-marshalling phases. As the client writes data to a stream this data is internally filled into fixed-size buffers and passed to the transport layer as soon as they are full enough. As a consequence the server already starts reading and processing that data while the client is still busy sending more data.
- Multiple virtual channels can be multiplexed through a single physical transport connection. Each such channel can be associated with its own signal protocol and then be used to multiplex arbitrary numbers of signals into both directions.
- The client and server roles do only apply while establishing a physical transport connection. Once connected both sides can open virtual channels at arbitrary times and send or receive data, possibly through signals.
I hope some of you found this interesting. Maybe I have some more ideas for articles about Net4j in the future...