Application

At the heart of Babl server is your Application where your business logic is executed.

Your application is executed on a single thread, and will be invoked when:

When running in DIRECT mode, your application is invoked on the thread that processes network I/O and handles web-socket protocol framing.

When running in DETACHED mode, your application is invoked on its own thread.

For more detail on the two different modes, see Architecture.

The Application Interface

Your business logic component must implement the Application interface, shown below.

package com.aitusoftware.babl.user;

import com.aitusoftware.babl.websocket.DisconnectReason;
import com.aitusoftware.babl.websocket.Session;

import org.agrona.DirectBuffer;

public interface Application
{
    int onSessionConnected(
        Session session);

    int onSessionDisconnected(
        Session session,
        DisconnectReason reason);

    int onSessionMessage(
        Session session,
        ContentType contentType,
        DirectBuffer msg,
        int offset,
        int length);
}
        

Applications may maintain a reference to a Session object between connected and disconnected events.

Applications must not invoke any method on a Session object from a thread other than the application thread.

The Echo Application

The simplest example application is to simply to echo back messages to the client connection.

This application is deployed in the example container described in Getting Started.

public final class EchoApplication implements Application
{
    private final MutableDirectBuffer buffer =
        new ExpandableDirectByteBuffer(512);

    @Override
    public int onSessionConnected(
        final Session session)
    {
        System.out.printf("Session %d connected%n", session.id());
        return SendResult.OK;
    }

    @Override
    public int onSessionDisconnected(
        final Session session,
        final DisconnectReason reason)
    {
        System.out.printf("Session %d disconnected due to %s%n",
            session.id(), reason.name());
        return SendResult.OK;
    }

    @Override
    public int onSessionMessage(
        final Session session,
        final ContentType contentType,
        final DirectBuffer msg,
        final int offset,
        final int length)
    {
        // copy request data to outbound buffer
        buffer.putBytes(0, msg, offset, length);
        int sendResult;
        do
        {
            // send buffer to session
            sendResult = session.send(contentType, buffer, 0, length);
        }
        while (sendResult != SendResult.OK);

        return sendResult;
    }
}
        

Application Work

When it is necessary to perform extra work on the application thread (e.g. polling an external message transport), this can be configured by supplying an extra Agent to the application configuration:

private void configureApplication(final BablConfig bablConfig)
{
    final Agent pollingAgent = createPollingAgent();
    bablConfig.applicationConfig().additionalWork(pollingAgent);
}

The additional Agent will be invoked on each duty-cycle, after the application.