Skip to content
js-labs edited this page Mar 10, 2014 · 5 revisions

Object model

Any network framework has a few key point requiring user interaction, they are:

  • new TCP/IP session
  • some data is ready to be processed
  • session close

The TCP/IP session in the JS-Collider framework is linked to the Session class instance and has a listener object responsible to handle session events (such as new data available and session close).

Empty Collider

Creating and running the Collider instance looks like:

public class ColliderApplication
{
    public static void main( String[] args )
    {
        try {
            final Collider collider = Collider.create();
            collider.run();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Collider.run() method will not return until Collider.stop() method call. Let's add some more.

Accepting income connections

In a case if application needs to accept income TCP/IP connections it should use Acceptor derived class which acts as a set of configuration properties and a factory for the session listeners. First of all we will need to implement a Session.Listener interface which will handle session events:

class ServerListener extends Session.Listener
{
    private final Session session;

    public ServerListener( Session session )
    {
        this.session = session;
        System.out.println( session.getRemoteAddress() + ": connection accepted." );
    }

    public void onDataReceived( ByteBuffer data )
    {
        /* Let's just send the received data back.
         * data object is valid only during the onDataReceived() call,
         * Session.sendData() method is asynchronous, so we have to make a copy.
         */
         final int bytesReceived = data.remaining();
         final ByteBuffer byteBuffer = ByteBuffer.allocateDirect( bytesReceived );
         byteBuffer.put( data );
         byteBuffer.flip();
         session.sendData( byteBuffer );
    }

    public void onConnectionClosed()
    {
        System.out.println( session.getRemoteAddress() + ": connection closed." );
    }
}

That's it. The important thing is that ByteBuffer argument of the onDataReceived() method is valid only during the call. User should not retain it. The position in the ByteBuffer can be greater than 0, but still the data in a [position, limit] range is data to be handled.

Session listener class can not live on it's own. We need some code to instantiate listener object.

class ServerAcceptor extends Acceptor
{
    public Session.Listener createSessionListener( Session session )
    {
        return new ServerListener( session );
    }
}

Let's start an acceptor:

public class ColliderApplication
{
    private static final int PORT_NUMBER = 12345;

    public static void main( String[] args )
    {
        try {
            final Collider collider = Collider.create();
            collider.addAcceptor( new ServerAcceptor(new InetSocketAddress(PORT_NUMBER)) );
            collider.run();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
Clone this wiki locally