private void onChannelAcceptable(SelectionKey key) throws IOException { ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); SelectionKey readKey = socketChannel.register(selector, SelectionKey.OP_READ); readKey.attach(key.attachment()); }
/** * Writes the pending {@link ByteBuffer} to the underlying channel sending data to the intended * receiver of the packet. */ @Override protected void doWrite(Object pendingWrite, SelectionKey key) throws IOException { ByteBuffer pendingBuffer = (ByteBuffer) pendingWrite; ((SocketChannel) key.channel()).write(pendingBuffer); } }
/** * Creates a reactor which will use provided {@code dispatcher} to dispatch events. The application can provide * various implementations of dispatcher which suits its needs. * * @param dispatcher * a non-null dispatcher used to dispatch events on registered channels. * @throws IOException * if any I/O error occurs. */ public NioReactor(Dispatcher dispatcher) throws IOException { this.dispatcher = dispatcher; this.selector = Selector.open(); }
private void processKey(SelectionKey key) throws IOException { if (key.isAcceptable()) { onChannelAcceptable(key); } else if (key.isReadable()) { onChannelReadable(key); } else if (key.isWritable()) { onChannelWritable(key); } }
@Override public boolean finishConnect() throws IOException { boolean connected = socketChannel.finishConnect(); if (connected) key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT | SelectionKey.OP_READ); return connected; }
/** * Creates a {@link ServerSocketChannel} which will bind at provided port and use * <code>handler</code> to handle incoming events on this channel. * <p> * Note the constructor does not bind the socket, {@link #bind()} method should be called for * binding the socket. * * @param port the port on which channel will be bound to accept incoming connection requests. * @param handler the handler that will handle incoming requests on this channel. * @throws IOException if any I/O error occurs. */ public NioServerSocketChannel(int port, ChannelHandler handler) throws IOException { super(handler, ServerSocketChannel.open()); this.port = port; }
@Override public SocketChannel run() throws IOException { return serverSocketChannel.accept(); } });
@Override public void close() throws IOException { delegate.close(); } }
void cancel(SelectionKey key) { key.cancel(); cancelledKeys ++; if (cancelledKeys >= CLEANUP_INTERVAL) { cancelledKeys = 0; needsToSelectAgain = true; } }
@Override public Boolean run() throws IOException { return socketChannel.connect(remoteAddress); } });
/** * Registers a new channel (handle) with this reactor. Reactor will start waiting for events on this channel and * notify of any events. While registering the channel the reactor uses {@link AbstractNioChannel#getInterestedOps()} * to know about the interested operation of this channel. * * @param channel * a new channel on which reactor will wait for events. The channel must be bound prior to being registered. * @return this * @throws IOException * if any I/O error occurs. */ public NioReactor registerChannel(AbstractNioChannel channel) throws IOException { SelectionKey key = channel.getJavaChannel().register(selector, channel.getInterestedOps()); key.attach(channel); channel.setReactor(this); return this; }
public void run() { key.interestOps(interestedOps); }
private static void onChannelWritable(SelectionKey key) throws IOException { AbstractNioChannel channel = (AbstractNioChannel) key.attachment(); channel.flush(key); }
/** * This implementation opens a FileChannel for the underlying file. * @see java.nio.channels.FileChannel */ @Override public WritableByteChannel writableChannel() throws IOException { return FileChannel.open(this.filePath, StandardOpenOption.WRITE); }
@Override public void write(int b) throws IOException { throw new ClosedChannelException(); } };
@Override public byte[] read() throws IOException { try (SeekableByteChannel channel = Files.newByteChannel(path, options)) { return ByteStreams.toByteArray(Channels.newInputStream(channel), channel.size()); } }
@Override public boolean isOpen() { return ch.isOpen(); }
@Override public Void run() throws IOException { networkChannel.bind(address); return null; } });
@Override public Void run() throws IOException { socketChannel.bind(address); return null; } });
/** * does socketChannel.finishConnect() */ @Override public boolean finishConnect() throws IOException { boolean connected = socketChannel.finishConnect(); if (connected) key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT | SelectionKey.OP_READ); return connected; }