/* * (c) Copyright 2009 Hewlett-Packard Development Company, LP * All rights reserved. * [See endLog of file] */ package riot.comms.server.nio; import java.io.IOException ; import java.io.InputStream ; import java.io.OutputStream ; import java.net.InetSocketAddress ; import java.net.ServerSocket ; import java.net.Socket ; import java.net.SocketAddress ; import java.nio.channels.SelectionKey ; import java.nio.channels.Selector ; import java.nio.channels.ServerSocketChannel ; import java.nio.channels.SocketChannel ; import java.util.Iterator ; import org.slf4j.Logger ; import org.slf4j.LoggerFactory ; import riot.comms.CommsException ; import riot.comms.server.Server ; import riot.comms.server.Service ; import riot.comms.server.ServiceType ; import riot.comms.server.socket.ServerRequestHandler ; /** Basic channel handling with NIO */ class NioServer extends Server implements Service, Runnable { // Needs work - the handling of request sis still socket style. // Change to selectors and have a tread pool that can pick up continuations? // See other systems - maybe this is no help. private static Logger log = LoggerFactory.getLogger(NioServer.class) ; private int port ; private SocketAddress serverEndpoint ; private ServerRequestHandler requestHandler ; public NioServer(int port, String label, ServiceType serviceType, ServerRequestHandler requestHandler) { super(serviceType) ; this.port = port ; serverEndpoint = new InetSocketAddress(port) ; this.requestHandler = requestHandler ; } volatile boolean shutdown = false ; @Override public void start() {} /** Gracefully stop */ @Override public void stop() { shutdown = true ; } @Override public void run() { server() ; } void server() { try { Selector selector = Selector.open() ; ServerSocketChannel chann = ServerSocketChannel.open() ; // Listener ServerSocket sock = chann.socket() ; sock.bind(serverEndpoint, 10) ; chann.configureBlocking(false) ; // Only valid operation for this socket - it's a listener. int ops = SelectionKey.OP_ACCEPT ; //| SelectionKey.OP_CONNECT //| SelectionKey.OP_READ //| SelectionKey.OP_WRITE //; SelectionKey key = chann.register(selector, ops) ; while ( true ) { if ( shutdown ) break ; int readyCount = selector.select() ; if ( readyCount == 0 ) continue ; if ( log.isTraceEnabled() ) log.trace("Ready Count = "+readyCount) ; Iterator iter = selector.selectedKeys().iterator() ; for ( ; iter.hasNext(); ) { SelectionKey sKey = iter.next(); //log.info("sKey = "+sKey) ; if ( sKey.isAcceptable() ) { if ( log.isDebugEnabled() ) log.debug("Accept") ; ServerSocketChannel server = (ServerSocketChannel)key.channel() ; SocketChannel ch = server.accept() ; //ch.configureBlocking(true) ; Socket socket = ch.socket() ; InputStream inputStream = socket.getInputStream() ; OutputStream outputStream = socket.getOutputStream() ; requestHandler.handleRequests(inputStream, outputStream) ; //ch.register(selector, SelectionKey.OP_READ) ; } else if ( sKey.isConnectable() ) { // Unexpected because this is a server (does not initiate outgoing conenctions). throw new CommsException("Unexpected connectable key") ; } else if ( sKey.isReadable() ) { if ( log.isDebugEnabled() ) log.debug("Read event") ; //netEventHandler.read(sKey) ; } else if ( sKey.isWritable() ) { if ( log.isDebugEnabled() ) log.debug("Write event") ; //netEventHandler.write(sKey) ; } else { throw new CommsException("Unexpected selector key") ; } iter.remove() ; } } } catch (IOException ex) { ex.printStackTrace(); } log.info("Server exit") ; } } /* * (c) Copyright 2009 Hewlett-Packard Development Company, LP * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */