10.4. Robust Connection

In Chapter 6, the concept of Comet and nonblocking IO was briefly introduced. The context there was scalable messaging and real-time data pushing. In this section, I extend the discussion to a more generic discussion on nonblocking IO in Java. The concepts here can be leveraged to build nonblocking channels that will work well with most existing channel types and could also serve well to create nonblocking socket connections between a Flex application and a BlazeDS server. Non-blocking channels allow for a greater number of connections to be served provided they are not all active at the same time always. LCDS uses NIO channels for connection scalability. You can include the same robustness in BlazeDS as well. Only Java NIO fundamentals are covered in this section.

As a result of JSR 51 efforts and starting with Java 1.4, a new IO package is available in Java. It's appropriately called the New IO, or NIO for short. The NIO package includes a number of new improvements to the traditional IO in Java. The one that we are interested in the context of this section is the ability to create nonblocking sockets, which allows input/output operations on a channel without blocking the underlying processes. This is a great new feature. Traditional multi-threaded servers for processing multiple simultaneous client requests can now be replaced in many situations with nonblocking sockets.

NIO nonblocking channels utilize a java.nio.Buffer to read and write data. A Buffer supports all Java primitive types. You can think of a Buffer as a stream. You can write to it and read from it. It has a current position, sort of a cursor, at all times. After reading a particular value, the cursor moves to the next item in the Buffer. A buffer defines a capacity and you can set a limit to the capacity while reading and writing data. Data is written to a buffer using the put method and read from it using the get method.

In a NIO nonblocking socket server, an important intermediary called the selector sits between a socket channel and the socket server. The selector takes incoming requests, assigns them a key and passes them on to the server to process. This is what creates the asynchronous scalable model.

The key, apart from a reference to the request, also holds the request type, which could be:

  • Client attempting to connect

  • Server attempting to connect

  • Reading operation

  • Writing operation

The server itself listens for new requests in an infinite loop. The server infinite loop could be as follows:

for(;;) {

  selector.select();

  Set keys = selector.selectedKeys();
  Iterator i = keys.iterator();

  while(i.hasNext()) {
    SelectionKey key = (SelectionKey) i.next();

    i.remove();

    if (key.isAcceptable()) {

      SocketChannel client = server.accept();
      client.configureBlocking(false);
      client.register(selector, SelectionKey.OP_READ);
      continue;
    }

    if (key.isReadable()) {

      SocketChannel client = (SocketChannel) key.channel();

     int BUFFER_SIZE = 32;
      ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
      try {
        client.read(buffer);
      }
      catch (Exception e) {
        e.printStackTrace();
        continue;
      }

      buffer.flip();
      Charset charset=Charset.forName("ISO-8859-1");
      CharsetDecoder decoder = charset.newDecoder();
      CharBuffer charBuffer = decoder.decode(buffer);
      System.out.print(charBuffer.toString());
      continue;
    }
  }
}

In the code snippet above you will notice that the server waits in an infinite loop for requests to come. As requests arrive a selector intercepts them and attaches a key before passing it on to the server. In the server, the waiting request listener iterates through the set of keys. For each key, it checks for the isAcceptable and isReadable states. If isAcceptable is true then a client requires a connection, which is established. If isReadable is true then a server is ready to read. In the simple example above once the connection is established and a server is ready to read, bytes are read and the output is sent to console. You can modify existing BlazeDS channels to include Java NIO style socket servers for connection handling while keeping the functionality as before.

After a sneak peek into how asynchronous nonblocking IO could make connections more robust and scalable, let's move on to the architectural issue of service orientation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.50.87