Sample

Assume we have two services: add and sub, which are responsible for adding and subtracting passed integer values. The services protocol could be descibed by the following ABNF:

From the protocol description, it's obvious we can distinguish two services and their protocols by 3-bytes magic header, add-service has "add", sub-service "sub". So it's what service's ProtocolFinder should address. For example add-service ProtocolFinder may look like:

/**
 * {@link ProtocolFinder}, responsible to determine if incoming byte buffer
 * represents ADD-service request.
 */
public class AddProtocolFinder implements ProtocolFinder {

    private final static byte[] magic = {'a', 'd', 'd'};

    /**
     * {@inheritDoc}
     */
    @Override
    public Result find(final PUContext puContext, final FilterChainContext ctx) {
        // Get the input Buffer
        final Buffer inputBuffer = ctx.getMessage();

        final int bytesToCompare = Math.min(magic.length, inputBuffer.remaining());
        
        final int bufferStart = inputBuffer.position();

        // Compare incoming bytes with ADD-service protocol magic
        for (int i = 0; i < bytesToCompare; i++) {
            if (magic[i] != inputBuffer.get(bufferStart + i)) {
                // If at least one byte doesn't match - it's not ADD-service protocol
                return Result.NOT_FOUND;
            }
        }

        // if we check entire magic - return FOUND, or NEED_MORE_DATA otherwise
        return bytesToCompare == magic.length ?
            Result.FOUND : Result.NEED_MORE_DATA;
    }

}

The add-service FilterChain will contain two Filters:

The PUProtocol initialization and registration for add-service will look following way:

        // Create PUFilter
        final PUFilter puFilter = new PUFilter();

        // Create ADD-service ProtocolFinder
        final ProtocolFinder addProtocolFinder = new AddProtocolFinder();

        // Create ADD-service FilterChain
        final FilterChain addProtocolFilterChain =
                puFilter.getPUFilterChainBuilder()
                // Add ADD-service message parser/serializer
                .add(new AddServerMessageFilter())
                // Add ADD-service filter
                .add(new AddServiceFilter())
                .build();

        // Construct PUProtocol
        final PUFilter addServicePUProtocol = new PUProtocol(addProtocolFinder, addProtocolFilterChain);

        // Register add-service pu protocol
        puFilter.register(addServicePUProtocol);

Similar coding is required for the sub-service. Finally port unification Filter (PUFilter) should be added to the main FilterChain and Transport could be started

        // Construct the main filter chain
        final FilterChainBuilder puFilterChainBuilder = FilterChainBuilder.stateless()
                .add(new TransportFilter())
                .add(puFilter);

        // Build TCP transport
        final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
        transport.setProcessor(puFilterChainBuilder.build());

        // Bind to the server port
        transport.bind(PORT);
        // Start
        transport.start();

Complete sample code could be found here.