@Override protected SelectChannelEndPoint newEndPoint( SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException { // We're connected, cancel the connect timeout Timeout.Task connectTimeout = _connectingChannels.remove(channel); if (connectTimeout != null) connectTimeout.cancel(); if (LOG.isDebugEnabled()) LOG.debug("Channels with connection pending: {}", _connectingChannels.size()); // key should have destination at this point (will be replaced by endpoint after this call) HttpDestination dest = (HttpDestination) key.attachment(); SelectChannelEndPoint scep = new SelectChannelEndPoint(channel, selectSet, key, (int) _httpClient.getIdleTimeout()); AsyncEndPoint ep = scep; if (dest.isSecure()) { LOG.debug("secure to {}, proxied={}", channel, dest.isProxied()); ep = new UpgradableEndPoint(ep, newSslEngine(channel)); } AsyncConnection connection = selectSet.getManager().newConnection(channel, ep, key.attachment()); ep.setConnection(connection); AbstractHttpConnection httpConnection = (AbstractHttpConnection) connection; httpConnection.setDestination(dest); if (dest.isSecure() && !dest.isProxied()) ((UpgradableEndPoint) ep).upgrade(); dest.onNewConnection(httpConnection); return scep; }
@Override public void handle(SelectionKey key, Selector selector) { if (null == key.attachment()) { System.out.println("key.attachment() is null ... "); return; } FileSender sender = (FileSender) key.attachment(); System.out.println("get write request.attachemnt fileName : " + sender); // send file and register read sender.send((SocketChannel) key.channel()); }
@Override public void onRead(SelectionKey key) throws Exception { channel = (SocketChannel) key.channel(); if (cursor == null) { if (key.attachment() instanceof Object[]) { Object[] ar = (Object[]) key.attachment(); for (Object o : ar) { if (o instanceof ByteBuffer) { cursor = (ByteBuffer) o; continue; } if (o instanceof Rfc822HeaderState) { req = ((Rfc822HeaderState) o).$req(); continue; } } } key.attach(this); } cursor = null == cursor ? ByteBuffer.allocateDirect(getReceiveBufferSize()) : cursor.hasRemaining() ? cursor : ByteBuffer.allocateDirect(cursor.capacity() << 1) .put((ByteBuffer) cursor.rewind()); int read = channel.read(cursor); if (read == -1) key.cancel(); Buffer flip = cursor.duplicate().flip(); req = (HttpRequest) ActionBuilder.get().state().$req().apply((ByteBuffer) flip); if (!BlobAntiPatternObject.suffixMatchChunks(HEADER_TERMINATOR, req.headerBuf())) { return; } cursor = ((ByteBuffer) flip).slice(); /* int remaining = Integer.parseInt(req.headerString(HttpHeaders.Content$2dLength)); final Impl prev = this; if (cursor.remaining() != remaining) key.attach(new Impl() { @Override public void onRead(SelectionKey key) throws Exception { int read1 = channel.read(cursor); if (read1 == -1) key.cancel(); if (!cursor.hasRemaining()) { key.interestOps(SelectionKey.OP_WRITE).attach(prev); return; } } });*/ key.interestOps(SelectionKey.OP_WRITE); }
private void close(SelectionKey key) { try { RapidoidConnection conn = (RapidoidConnection) key.attachment(); if (key.isValid()) { SocketChannel socketChannel = (SocketChannel) key.channel(); socketChannel.close(); key.attach(null); key.cancel(); } if (conn != null) { if (!conn.closed) { U.trace("Closing connection", "connection", conn); conn.closed = true; assert conn.key == key; conn.key = null; connections.release(conn); } } } catch (IOException e) { e.printStackTrace(); } }
private void doAsyncWrite(SelectionKey key) throws IOException { Call call = (Call) key.attachment(); if (call == null) { return; } if (key.channel() != call.connection.channel) { throw new IOException("doAsyncWrite: bad channel"); } synchronized (call.connection.responseQueue) { if (processResponse(call.connection.responseQueue, false)) { try { key.interestOps(0); } catch (CancelledKeyException e) { /* * The Listener/reader might have closed the socket. * We don't explicitly cancel the key, so not sure if this will * ever fire. * This warning could be removed. */ LOG.warn("Exception while changing ops : " + e); } } } }
void doRead(SelectionKey key) throws InterruptedException { int count = 0; Connection c = (Connection) key.attachment(); if (c == null) { return; } c.setLastContact(System.currentTimeMillis()); try { count = c.readAndProcess(); } catch (InterruptedException ieo) { LOG.info(getName() + ": readAndProcess caught InterruptedException", ieo); throw ieo; } catch (Exception e) { LOG.info( getName() + ": readAndProcess threw exception " + e + ". Count of bytes read: " + count, e); count = -1; // so that the (count < 0) block is executed } if (count < 0) { closeConnection(c); c = null; } else { c.setLastContact(System.currentTimeMillis()); } }
/** * Accept new connection. * * @param key */ final void accept(SelectionKey key) { try { ((Acceptor) key.attachment()).accept(key); } catch (Exception e) { log.error("Error while accepting connection: +" + e, e); } }
/** Selects on sockets and informs their Communicator when there is something to do. */ public void communicate(int timeout) { try { selector.select(timeout); } catch (IOException e) { // Not really sure why/when this happens yet return; } Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) continue; // WHY Communicator communicator = (Communicator) key.attachment(); if (key.isReadable()) communicator.onReadable(); if (key.isWritable()) communicator.onWritable(); if (key.isAcceptable()) communicator.onAcceptable(); } // Go through the queue and handle each communicator while (!queue.isEmpty()) { Communicator c = queue.poll(); c.onMemo(); } }
private void processConnectTimeout(Set<SelectionKey> keys, long currentTimeNanos) { ConnectException cause = null; for (SelectionKey k : keys) { if (!k.isValid()) { // Comment the close call again as it gave us major problems with ClosedChannelExceptions. // // See: // * https://github.com/netty/netty/issues/142 // * https://github.com/netty/netty/issues/138 // // close(k); continue; } NioClientSocketChannel ch = (NioClientSocketChannel) k.attachment(); if (ch.connectDeadlineNanos > 0 && currentTimeNanos >= ch.connectDeadlineNanos) { if (cause == null) { cause = new ConnectException("connection timed out"); } ch.connectFuture.setFailure(cause); fireExceptionCaught(ch, cause); ch.worker.close(ch, succeededFuture(ch)); } } }
/** * Method writePacket. * * @param key SelectionKey */ protected void writePacket(SelectionKey key) { MMOConnection<T> con = (MMOConnection<T>) key.attachment(); prepareWriteBuffer(con); DIRECT_WRITE_BUFFER.flip(); int size = DIRECT_WRITE_BUFFER.remaining(); int result = -1; try { result = con.getWritableChannel().write(DIRECT_WRITE_BUFFER); } catch (IOException e) { // error handling goes on the if bellow } // check if no error happened if (result >= 0) { stats.increaseOutgoingBytes(result); // check if we written everything if (result != size) { con.createWriteBuffer(DIRECT_WRITE_BUFFER); } if (!con.getSendQueue().isEmpty() || con.hasPendingWriteBuffer()) { con.scheduleWriteInterest(); } } else { con.onForcedDisconnection(); closeConnectionImpl(con); } }
/** * @throws IOException due to {@link SocketChannel#write(ByteBuffer)} call * @throws CancelledKeyException * @see * com.niffy.AndEngineLockStepEngine.threads.nio.BaseSelectorThread#write(java.nio.channels.SelectionKey) */ @Override protected void write(SelectionKey pKey) throws IOException, CancelledKeyException { DatagramChannel socketChannel; String connectionIP; socketChannel = (DatagramChannel) pKey.channel(); InetSocketAddress address = (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress(); connectionIP = address.getAddress().getHostAddress(); InetSocketAddress target = (InetSocketAddress) pKey.attachment(); synchronized (this.mPendingData) { ArrayList<ByteBuffer> queue = this.mPendingData.get(target.getAddress()); // Write until there's not more data ... while (!queue.isEmpty()) { ByteBuffer buf = (ByteBuffer) queue.get(0); socketChannel.send(buf, target); if (buf.remaining() > 0) { // ... or the socket's buffer fills up break; } queue.remove(0); } if (queue.isEmpty()) { // We wrote away all data, so we're no longer interested // in writing on this socket. Switch back to waiting for // data. pKey.interestOps(SelectionKey.OP_READ); } } }
/** * writes all the entries that have changed, to the buffer which will later be written to TCP/IP * * @param modificationIterator a record of which entries have modification * @param selectionKey */ void entriesToBuffer( @NotNull final ModificationIterator modificationIterator, @NotNull final SelectionKey selectionKey) throws InterruptedException, IOException { final SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); final Attached attached = (Attached) selectionKey.attachment(); // this can occur when new SHM's are added to a cluster final boolean handShakingComplete = attached.isHandShakingComplete(); for (; ; ) { final boolean wasDataRead = modificationIterator.nextEntry(entryCallback, 0); if (!wasDataRead) { // if we have no more data to write to the socket then we will // un-register OP_WRITE on the selector, until more data becomes available if (in.position() == 0 && handShakingComplete) disableWrite(socketChannel, attached); return; } // we've filled up the buffer lets give another channel a chance to send some data if (in.remaining() <= maxEntrySizeBytes) return; // if we have space in the buffer to write more data and we just wrote data into the // buffer then let try and write some more } }
/** * check to see if we have lost connection with the remote node and if we have attempts a * reconnect. * * @param key the key relating to the heartbeat that we are checking * @param approxTimeOutTime the approximate time in milliseconds * @throws ConnectException */ private void heartbeatCheckHasReceived( @NotNull final SelectionKey key, final long approxTimeOutTime) throws ConnectException { final Attached attached = (Attached) key.attachment(); // we wont attempt to reconnect the server socket if (attached.isServer || !attached.isHandShakingComplete()) return; final SocketChannel channel = (SocketChannel) key.channel(); if (approxTimeOutTime > attached.entryReader.lastHeartBeatReceived + attached.remoteHeartbeatInterval) { if (LOG.isDebugEnabled()) LOG.debug( "lost connection, attempting to reconnect. " + "missed heartbeat from identifier=" + attached.remoteIdentifier); try { channel.socket().close(); channel.close(); activeKeys.clear(attached.remoteIdentifier); closeables.remove(channel); } catch (IOException e) { LOG.debug("", e); } attached.connector.connectLater(); } }
public void serve(int port) throws IOException { ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); ServerSocket ss = serverChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); // Binds the server to the selected port ss.bind(address); // Opens the Selector for handling channels Selector selector = Selector.open(); // Registers the ServerSocket with the Selector to accept connections serverChannel.register(selector, SelectionKey.OP_ACCEPT); final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes()); while (true) { try { // Waits for new events to process; blocks until the next incoming event selector.select(); } catch (IOException e) { e.printStackTrace(); break; } // Obtains all SelectionKey instances that received events Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); try { // Checks if the event is a new connection ready to be accepted if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); // Accepts client and registers it with the selector client.register( selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate()); System.out.println("Accepted connection from " + client); } // Checks if the socket is ready for writing data if (key.isWritable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); while (buffer.hasRemaining()) { // Writes data to the connected client if (client.write(buffer) == 0) { break; } } // Closes the connection client.close(); } } catch (IOException e) { key.cancel(); try { key.channel().close(); } catch (IOException e1) { } } } } }
private void processEvent(final SelectionKey key) throws IOReactorException { try { if (key.isAcceptable()) { ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = null; try { socketChannel = serverChannel.accept(); } catch (IOException ex) { if (this.exceptionHandler == null || !this.exceptionHandler.handle(ex)) { throw new IOReactorException("Failure accepting connection", ex); } } if (socketChannel != null) { try { prepareSocket(socketChannel.socket()); } catch (IOException ex) { if (this.exceptionHandler == null || !this.exceptionHandler.handle(ex)) { throw new IOReactorException("Failure initalizing socket", ex); } } ChannelEntry entry = new ChannelEntry(socketChannel); addChannel(entry); } } } catch (CancelledKeyException ex) { ListenerEndpoint endpoint = (ListenerEndpoint) key.attachment(); this.endpoints.remove(endpoint); key.attach(null); } }
void isReadable(SelectionKey k) { EventableChannel ec = (EventableChannel) k.attachment(); long b = ec.getBinding(); if (ec.isWatchOnly()) { if (ec.isNotifyReadable()) eventCallback(b, EM_CONNECTION_NOTIFY_READABLE, null); } else { myReadBuffer.clear(); try { ec.readInboundData(myReadBuffer); myReadBuffer.flip(); if (myReadBuffer.limit() > 0) { if (ProxyConnections != null) { EventableChannel target = ProxyConnections.get(b); if (target != null) { ByteBuffer myWriteBuffer = ByteBuffer.allocate(myReadBuffer.limit()); myWriteBuffer.put(myReadBuffer); myWriteBuffer.flip(); target.scheduleOutboundData(myWriteBuffer); } else { eventCallback(b, EM_CONNECTION_READ, myReadBuffer); } } else { eventCallback(b, EM_CONNECTION_READ, myReadBuffer); } } } catch (IOException e) { UnboundConnections.add(b); } } }
public void run() { try { while (selectable) { // The select() will be woke up if some new connection // have occurred, or if the selector has been explicitly // woke up if (selector.select() > 0) { Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); if (key.isValid()) { EventHandler processor = ((EventHandler) key.attachment()); processor.process(key); } } } } } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Error while waiting for events", ioe); } finally { if (selectable) { LOGGER.log( Level.WARNING, "Unexpected death of thread {0}", Thread.currentThread().getName()); } else { LOGGER.log( Level.FINE, "Thread {0} termination initiated by call to AgentServer.close()", Thread.currentThread().getName()); } } }
// Process keys that have become selected // void processSelectedKeys() throws IOException { for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) { // Retrieve the next key and remove it from the set SelectionKey sk = (SelectionKey) i.next(); i.remove(); // Retrieve the target and the channel Target t = (Target) sk.attachment(); SocketChannel sc = (SocketChannel) sk.channel(); // Attempt to complete the connection sequence try { if (sc.finishConnect()) { sk.cancel(); t.connectFinish = System.currentTimeMillis(); sc.close(); printer.add(t); } } catch (IOException x) { sc.close(); t.failure = x; printer.add(t); } } }
private void processWritableKey(SelectionKey key) { CrawlURL url = (CrawlURL) key.attachment(); SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) url.getHandlerAttr(_REQUEST_BUFFER); try { // 发送http请求,若发送完成,取消OP_WRITE。 int writtenBytes = 0; for (int i = WRITE_SPIN_COUNT; i > 0; i--) { writtenBytes = channel.write(buffer); // write success if (writtenBytes != 0) { url.setHandlerAttr(_LAST_SEND_REQUEST_MILLIS, System.currentTimeMillis()); url.setHandlerAttr( _REQUEST_ALREADY_SEND_SIZE, (Integer) url.getHandlerAttr(_REQUEST_ALREADY_SEND_SIZE) + writtenBytes); url.setHandlerAttr( _REQUEST_SEND_TIMES, (Integer) url.getHandlerAttr(_REQUEST_SEND_TIMES) + 1); break; } } boolean reqSendFinished = !buffer.hasRemaining(); url.setHandlerAttr(_REQUEST_SEND_FINISHED, reqSendFinished); url.setHandlerAttr(_REQUEST_SEND_FINISHED_MILLIS, reqSendFinished); if (reqSendFinished) { url.removeHandlerAttr(_REQUEST_BUFFER); key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); } } catch (IOException e) { logger.error("error send http request ! URL: " + url); cancelAndClose(key); url.setFetchStatus(FETCH_FAILED); url.getPipeline().resume(DefaultPipeline.EMPTY_MSG); } }
private void dispatchMessages() throws IOException { Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); EventSource source = (EventSource) key.attachment(); if (key.isValid()) { try { if (key.isAcceptable()) { EventSource newSource = source.accept(); if (newSource != null) newSources.add(newSource); } if (key.isReadable()) { source.read(); } if (key.isWritable()) { source.write(); } } catch (CancelledKeyException e) { } } it.remove(); } for (int i = 0; i < newSources.size(); i++) register(newSources.get(i)); if (!newSources.isEmpty()) newSources.clear(); }
@Override protected void writeOP(SelectionKey key) throws IOException { RapidoidConnection conn = (RapidoidConnection) key.attachment(); SocketChannel socketChannel = (SocketChannel) key.channel(); checkOnSameThread(); try { int wrote = conn.output.writeTo(socketChannel); conn.output.deleteBefore(wrote); boolean complete = conn.output.size() == 0; if (conn.closeAfterWrite() && complete) { close(conn); } else { if (complete) { key.interestOps(SelectionKey.OP_READ); } else { key.interestOps(SelectionKey.OP_READ + SelectionKey.OP_WRITE); } conn.wrote(complete); } } catch (IOException e) { close(conn); } }
public static void main(String[] args) throws Exception { SocketChannel sc = SocketChannel.open(); Selector sel = Selector.open(); if (sc.keyFor(sel) != null) throw new Exception("keyFor != null"); sc.configureBlocking(false); SelectionKey sk = sc.register(sel, SelectionKey.OP_READ, args); if (sc.keyFor(sel) != sk) throw new Exception("keyFor returned " + sc.keyFor(sel)); if (sk.attachment() != args) throw new Exception("attachment() returned " + sk.attachment()); Trivial t = new Trivial(); sk.attach(t); if (sk.attachment() != t) throw new Exception("Wrong attachment"); sk.isReadable(); sk.isWritable(); sk.isConnectable(); sk.isAcceptable(); }
@Override public void run() { final Selector selector = this.selector; for (; ; ) { ++reactCount; try { selector.select(1000L); register(selector); Set<SelectionKey> keys = selector.selectedKeys(); try { for (SelectionKey key : keys) { Object att = key.attachment(); System.out.println("attchment " + att); if (att != null && key.isValid()) { int readyOps = key.readyOps(); if ((readyOps & SelectionKey.OP_READ) != 0) { read((NIOConnection) att); } else if ((readyOps & SelectionKey.OP_WRITE) != 0) { write((NIOConnection) att); } else { key.cancel(); } } else { key.cancel(); } } } finally { keys.clear(); } } catch (Throwable e) { LOGGER.warn(name, e); } } }
private void doConnect(SelectionKey key) { SocketChannel sc = (SocketChannel) key.channel(); TCConnectionImpl conn = (TCConnectionImpl) key.attachment(); try { if (sc.finishConnect()) { sc.register(selector, SelectionKey.OP_READ, conn); conn.finishConnect(); } else { String errMsg = "finishConnect() returned false, but no exception thrown"; if (logger.isInfoEnabled()) { logger.info(errMsg); } conn.fireErrorEvent(new Exception(errMsg), null); } } catch (IOException ioe) { if (logger.isInfoEnabled()) { logger.info("IOException attempting to finish socket connection", ioe); } conn.fireErrorEvent(ioe, null); } }
/** * The background thread that adds sockets to the Poller, checks the poller for triggered events * and hands the associated socket off to an appropriate processor as events occur. */ @Override public void run() { // Loop until destroy() is called while (true) { boolean hasEvents = false; try { if (!close) { hasEvents = events(); if (wakeupCounter.getAndSet(-1) > 0) { // if we are here, means we have other stuff to do // do a non blocking select keyCount = selector.selectNow(); } else { keyCount = selector.select(selectorTimeout); } wakeupCounter.set(0); } if (close) { events(); timeout(0, false); try { selector.close(); } catch (IOException ioe) { log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe); } break; } } catch (Throwable x) { ExceptionUtils.handleThrowable(x); log.error("", x); continue; } // either we timed out or we woke up, process events first if (keyCount == 0) hasEvents = (hasEvents | events()); Iterator<SelectionKey> iterator = keyCount > 0 ? selector.selectedKeys().iterator() : null; // Walk through the collection of ready keys and dispatch // any active event. while (iterator != null && iterator.hasNext()) { SelectionKey sk = iterator.next(); NioSocketWrapper attachment = (NioSocketWrapper) sk.attachment(); // Attachment may be null if another thread has called // cancelledKey() if (attachment == null) { iterator.remove(); } else { iterator.remove(); processKey(sk, attachment); } } // while // process timeouts timeout(keyCount, hasEvents); } // while stopLatch.countDown(); }
@Override protected SelectChannelEndPoint newEndPoint( SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException { SelectChannelEndPoint endp = new SelectChannelEndPoint(channel, selectSet, key, 2000); endp.setConnection(selectSet.getManager().newConnection(channel, endp, key.attachment())); _lastEndp = endp; return endp; }
private void dispatch() throws IOException { sel.select(); for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) { SelectionKey sk = (SelectionKey) i.next(); i.remove(); Handler h = (Handler) sk.attachment(); h.handle(sk); } }
/** * 有通道可读, 调用Session的onRead, 把数据读到Session的私有输入缓冲 * * @param key * @throws IOException * @throws InterruptedException */ private void onRead(SelectionKey key) throws IOException { Session session = (Session) key.attachment(); try { session.onRead(); } catch (InterruptedException e) { logger.error("OOPS Exception:", e); Thread.currentThread().interrupt(); } }
@Override public void reportError(SelectionKey key, ErrorType e, String msg) throws IOException { String error = ErrorRespManager.getStringError(e, msg); BufferManager.resetBuffer(writeBufferWrapper.byteBuffer); BufferManager.addStringToBuffer(error, writeBufferWrapper); key.interestOps(SelectionKey.OP_WRITE); ((AttachmentHTTP) (key.attachment())).fullWrittenBuffer = true; LoggingManager.logReport("RESP - " + e.toString()); }
@Override public void handle(ReadEvent event) { SelectionKey key = event.getKey(); SocketChannel channel = (SocketChannel) key.channel(); Session session = (Session) key.attachment(); if (session.isClosed()) { return; } try { ChannelData data = session.getData(channel); ByteBuffer readBuffer = data.getReadBuffer(); int size = channel.read(readBuffer); if (size < 0) { session.close(); return; } readBuffer.flip(); handleRead(session, data.getType(), data.getReadBuffer()); } catch (Throwable t) { Logger.debug(t); session.close(); } }