Introduction


Simple Network Framework for Java (SNF4J) is an asynchronous event-driven network application framework for quick and easy development of network applications.

The SNF4J serves as a simple, lightweight and independent network application framework helping in developing of high performance and scalable network applications. It provides an asynchronous API via the Java NIO to handle various transports like TCP/IP and UDP/IP.

The framework is designed to be simple in use and moderately easy to understand. Application developers that like to keep their ear to the ground will not be overwhelm by a tone of source code. It is oriented towards delivering core networking functionality as transferring data between two or more communicating network applications in a simple but effective way. To provide privacy and integrity of transferred data it provides support for the SSL/TLS protocols.


Features

  • event-driven architecture
  • support for TCP and UDP sockets
  • support for SSL/TLS protocols
  • support for codec pipelines
  • unified API for supported transport types
  • no additional dependencies
  • customizable selector loop pooling
  • customizable logging
  • customizable thread model
  • customizable byte buffer allocation
  • customizable protocol engines


♦♦♦

How to...


This is only a very simple overview of the SNF4J API. It covers only basic concepts for implementing client and server networking applications with the SNF4J framework. More details can be found in the documentation and in the examples that are distributed along with the core source code.

Server side

Let's start with the server side. The first thing we have to do is create and start the selector loop that will process signals from the Java NIO.

SelectorLoop loop = new SelectorLoop();
loop.start();

Next, with the help of the Java NIO API we need to prepare a server socket channel that will handle incoming connections.

ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(PORT));

To implement server's logic we need to create a handler. It will be receiving events and read data from the selector loop.

public class ServerHandler extends AbstractStreamHandler {

  @Override
  public void read(byte[] data) {
    //Some code
  }
}

Now we are ready to register the server socket channel along with a session factory with the selector loop. From now on the server socket channel is ready for accepting incoming connection.

loop.register(channel, new AbstractSessionFactory() {

  @Override
  protected IStreamHandler createHandler(SocketChannel channel) {
    return new ServerHandler();
  }
});

And finally, we can wait till the selector loop ends.

loop.join();

Client side

The server is running so let's waste no time and start implementing the client side. The first step looks familiar.

SelectorLoop loop = new SelectorLoop();
loop.start();

Next, with the help of the Java NIO API we need to prepare a client socket channel that will handle the connection.

SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(InetAddress.getByName(HOST), PORT));

To implement the client's logic we need to create a handler that will process session events and write some data to the server side. In the snippet below the client will send some nice words once connected with the server and then gently close. In addition it will instruct the selector loop to gently stop once the client session ends.

public class ClientHandler extends AbstractStreamHandler {

  @Override
  public void read(byte[] data) {
    //Some code
  }

  @Override
  public void event(SessionEvent event) {
    switch (event) {
      case READY:
      getSession().write("Hello, World!".getBytes());
      getSession().close();
      break;
    }
  }

  @Override
  public ISessionConfig getConfig() {
    return new DefaultSessionConfig().setEndingAction(EndingAction.STOP);
  }
}

Now the hardest part is over so let's register with the selector loop.

loop.register(channel, new ClientHandler());

Finally, wait till the selector loop ends.

loop.join();