/**********************************************************\ | | | hprose | | | | Official WebSite: http://www.hprose.com/ | | http://www.hprose.org/ | | | \**********************************************************/ /**********************************************************\ * * * Acceptor.java * * * * hprose Acceptor class for Java. * * * * LastModified: Sep 19, 2016 * * Author: Ma Bingyao <andot@hprose.com> * * * \**********************************************************/ package hprose.net; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; public final class Acceptor extends Thread { private final Selector selector; private final ServerSocketChannel serverChannel; private final ReactorGroup reactor; private final ConnectionHandler handler; public Acceptor(String host, int port, ConnectionHandler handler, int reactorThreads) throws IOException { selector = Selector.open(); serverChannel = ServerSocketChannel.open(); ServerSocket serverSocket = serverChannel.socket(); InetSocketAddress address = (host == null) ? new InetSocketAddress(port) : new InetSocketAddress(host, port); serverSocket.bind(address); serverChannel.configureBlocking(false); serverChannel.register(selector, SelectionKey.OP_ACCEPT); reactor = new ReactorGroup(reactorThreads); this.handler = handler; } @Override public void run() { reactor.start(); try { while (!isInterrupted()) { try { process(); } catch (IOException e) { handler.onError(null, e); } } } catch (ClosedSelectorException e) {} reactor.close(); } private void process() throws IOException { int n = selector.select(); if (n == 0) return; Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); if (key.isAcceptable()) { accept(key); } } } private void accept(SelectionKey key) throws IOException { final SocketChannel channel = ((ServerSocketChannel) key.channel()).accept(); if (channel != null) { channel.configureBlocking(false); channel.socket().setReuseAddress(true); channel.socket().setKeepAlive(true); reactor.register(new Connection(channel, handler, null)); } } public void close() { try { selector.close(); } catch (IOException e) {} try { serverChannel.close(); } catch (IOException e) {} } }