@Override public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception { Object o = e.getMessage(); if (o instanceof FileRegionTransferCommand) { ChannelBuffer cb = ChannelBuffers.dynamicBuffer(); ChannelFuture future = e.getFuture(); final FileRegionTransferCommand command = (FileRegionTransferCommand) o; command.writeHeader(cb); Channels.write(ctx, future, cb); ChannelFuture fileFuture = Channels.write(ctx.getChannel(), command.getFileRegion()); // Channels.write(ctx, future, command.getFileRegion()); fileFuture.addListener( new ChannelFutureProgressListener() { public void operationComplete(ChannelFuture future) { command.getFileRegion().releaseExternalResources(); System.out.print("ÉÏ´«Íê³É"); System.out.println(" " + System.currentTimeMillis()); } public void operationProgressed( ChannelFuture future, long amount, long current, long total) { // (String.format("%s: %d / %d (+%d)%n", path, current, total, amount)); } }); } else { super.writeRequested(ctx, e); } }
private void handleAcceptedSocket(ChannelEvent e) { if (e instanceof ChannelStateEvent) { ChannelStateEvent event = (ChannelStateEvent) e; SctpChannelImpl channel = (SctpChannelImpl) event.getChannel(); ChannelFuture future = event.getFuture(); ChannelState state = event.getState(); Object value = event.getValue(); switch (state) { case OPEN: if (Boolean.FALSE.equals(value)) { channel.worker.close(channel, future); } break; case BOUND: case CONNECTED: if (value == null) { channel.worker.close(channel, future); } break; case INTEREST_OPS: channel.worker.setInterestOps(channel, future, (Integer) value); break; } } else if (e instanceof MessageEvent) { MessageEvent event = (MessageEvent) e; SctpChannelImpl channel = (SctpChannelImpl) event.getChannel(); boolean offered = channel.writeBuffer.offer(event); assert offered; channel.worker.writeFromUserCode(channel); } }
private void cleanUpWriteBuffer(SctpChannelImpl channel) { Exception cause = null; boolean fireExceptionCaught = false; // Clean up the stale messages in the write buffer. synchronized (channel.writeLock) { MessageEvent evt = channel.currentWriteEvent; if (evt != null) { // Create the exception only once to avoid the excessive overhead // caused by fillStackTrace. if (channel.isOpen()) { cause = new NotYetConnectedException(); } else { cause = new ClosedChannelException(); } ChannelFuture future = evt.getFuture(); channel.currentWriteBuffer.release(); channel.currentWriteBuffer = null; channel.currentWriteEvent = null; evt = null; future.setFailure(cause); fireExceptionCaught = true; } Queue<MessageEvent> writeBuffer = channel.writeBuffer; if (!writeBuffer.isEmpty()) { // Create the exception only once to avoid the excessive overhead // caused by fillStackTrace. if (cause == null) { if (channel.isOpen()) { cause = new NotYetConnectedException(); } else { cause = new ClosedChannelException(); } } for (; ; ) { evt = writeBuffer.poll(); if (evt == null) { break; } evt.getFuture().setFailure(cause); fireExceptionCaught = true; } } } if (fireExceptionCaught) { fireExceptionCaught(channel, cause); } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (server) { Channels.write(channel, e.getMessage(), e.getRemoteAddress()); } else { ChannelBuffer m = (ChannelBuffer) e.getMessage(); byte[] actual = new byte[m.readableBytes()]; m.getBytes(0, actual); int lastIdx = counter; for (int i = 0; i < actual.length; i++) { assertEquals(frames.getByte(ignoredBytes + i + lastIdx), actual[i]); } counter += actual.length; } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { Object msg = e.getMessage(); if (msg instanceof HttpRequest) { handleHttpRequest(ctx, (HttpRequest) msg); } else if (msg instanceof WebSocketFrame) { handleWebSocketFrame(ctx, (WebSocketFrame) msg); } }
@Override public void eventSunk(ChannelPipeline pipeline, ChannelEvent e) throws Exception { if (e instanceof ChannelStateEvent) { ChannelStateEvent event = (ChannelStateEvent) e; NioClientSocketChannel channel = (NioClientSocketChannel) event.getChannel(); ChannelFuture future = event.getFuture(); ChannelState state = event.getState(); Object value = event.getValue(); switch (state) { case OPEN: if (Boolean.FALSE.equals(value)) { channel.getWorker().close(channel, future); } break; case BOUND: if (value != null) { bind(channel, future, (SocketAddress) value); } else { channel.getWorker().close(channel, future); } break; case CONNECTED: if (value != null) { connect(channel, future, (SocketAddress) value); } else { channel.getWorker().close(channel, future); } break; case INTEREST_OPS: channel.getWorker().setInterestOps(channel, future, ((Integer) value).intValue()); break; } } else if (e instanceof MessageEvent) { MessageEvent event = (MessageEvent) e; NioSocketChannel channel = (NioSocketChannel) event.getChannel(); boolean offered = channel.writeBufferQueue.offer(event); assert offered; channel.getWorker().writeFromUserCode(channel); } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { // Send back the received message to the remote peer. transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes()); e.getChannel().write(e.getMessage()); }
private void write0(SctpChannelImpl channel) { boolean open = true; boolean addOpWrite = false; boolean removeOpWrite = false; long writtenBytes = 0; final SctpSendBufferPool sendBufferPool = this.sendBufferPool; final com.sun.nio.sctp.SctpChannel ch = channel.channel; final Queue<MessageEvent> writeBuffer = channel.writeBuffer; final int writeSpinCount = channel.getConfig().getWriteSpinCount(); synchronized (channel.writeLock) { channel.inWriteNowLoop = true; for (; ; ) { MessageEvent evt = channel.currentWriteEvent; SendBuffer buf; if (evt == null) { if ((channel.currentWriteEvent = evt = writeBuffer.poll()) == null) { removeOpWrite = true; channel.writeSuspended = false; break; } channel.currentWriteBuffer = buf = sendBufferPool.acquire(evt.getMessage()); } else { buf = channel.currentWriteBuffer; } ChannelFuture future = evt.getFuture(); try { long localWrittenBytes = 0; for (int i = writeSpinCount; i > 0; i--) { localWrittenBytes = buf.transferTo(ch); if (localWrittenBytes != 0) { writtenBytes += localWrittenBytes; break; } if (buf.finished()) { break; } } if (buf.finished()) { // Successful write - proceed to the next message. buf.release(); channel.currentWriteEvent = null; channel.currentWriteBuffer = null; evt = null; buf = null; future.setSuccess(); } else { // Not written fully - perhaps the kernel buffer is full. addOpWrite = true; channel.writeSuspended = true; if (localWrittenBytes > 0) { // Notify progress listeners if necessary. future.setProgress(localWrittenBytes, buf.writtenBytes(), buf.totalBytes()); } break; } } catch (AsynchronousCloseException e) { // Doesn't need a user attention - ignore. } catch (Throwable t) { buf.release(); channel.currentWriteEvent = null; channel.currentWriteBuffer = null; buf = null; evt = null; future.setFailure(t); fireExceptionCaught(channel, t); if (t instanceof IOException) { open = false; close(channel, succeededFuture(channel)); } } } channel.inWriteNowLoop = false; } if (open) { if (addOpWrite) { setOpWrite(channel); } else if (removeOpWrite) { clearOpWrite(channel); } } fireWriteComplete(channel, writtenBytes); }
@Override protected void write0(final AbstractNioChannel channel) { boolean addOpWrite = false; boolean removeOpWrite = false; long writtenBytes = 0; final SendBufferPool sendBufferPool = this.sendBufferPool; final DatagramChannel ch = ((NioDatagramChannel) channel).getJdkChannel().getChannel(); final Queue<MessageEvent> writeBuffer = channel.writeBufferQueue; final int writeSpinCount = channel.getConfig().getWriteSpinCount(); synchronized (channel.writeLock) { // inform the channel that write is in-progress channel.inWriteNowLoop = true; // loop forever... for (; ; ) { MessageEvent evt = channel.currentWriteEvent; SendBuffer buf; if (evt == null) { if ((channel.currentWriteEvent = evt = writeBuffer.poll()) == null) { removeOpWrite = true; channel.writeSuspended = false; break; } channel.currentWriteBuffer = buf = sendBufferPool.acquire(evt.getMessage()); } else { buf = channel.currentWriteBuffer; } try { long localWrittenBytes = 0; SocketAddress raddr = evt.getRemoteAddress(); if (raddr == null) { for (int i = writeSpinCount; i > 0; i--) { localWrittenBytes = buf.transferTo(ch); if (localWrittenBytes != 0) { writtenBytes += localWrittenBytes; break; } if (buf.finished()) { break; } } } else { for (int i = writeSpinCount; i > 0; i--) { localWrittenBytes = buf.transferTo(ch, raddr); if (localWrittenBytes != 0) { writtenBytes += localWrittenBytes; break; } if (buf.finished()) { break; } } } if (localWrittenBytes > 0 || buf.finished()) { // Successful write - proceed to the next message. buf.release(); ChannelFuture future = evt.getFuture(); channel.currentWriteEvent = null; channel.currentWriteBuffer = null; evt = null; buf = null; future.setSuccess(); } else { // Not written at all - perhaps the kernel buffer is full. addOpWrite = true; channel.writeSuspended = true; break; } } catch (final AsynchronousCloseException e) { // Doesn't need a user attention - ignore. } catch (final Throwable t) { buf.release(); ChannelFuture future = evt.getFuture(); channel.currentWriteEvent = null; channel.currentWriteBuffer = null; buf = null; evt = null; future.setFailure(t); fireExceptionCaught(channel, t); } } channel.inWriteNowLoop = false; // Initially, the following block was executed after releasing // the writeLock, but there was a race condition, and it has to be // executed before releasing the writeLock: // // https://issues.jboss.org/browse/NETTY-410 // if (addOpWrite) { setOpWrite(channel); } else if (removeOpWrite) { clearOpWrite(channel); } } Channels.fireWriteComplete(channel, writtenBytes); }