use of io.netty.channel.socket.DuplexChannel in project netty by netty.
the class SocketHalfClosedTest method testHalfClosureOnlyOneEventWhenAutoRead.
public void testHalfClosureOnlyOneEventWhenAutoRead(ServerBootstrap sb, Bootstrap cb) throws Throwable {
Channel serverChannel = null;
try {
cb.option(ChannelOption.ALLOW_HALF_CLOSURE, true).option(ChannelOption.AUTO_READ, true);
sb.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelActive(ChannelHandlerContext ctx) {
((DuplexChannel) ctx).shutdownOutput();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
final AtomicInteger shutdownEventReceivedCounter = new AtomicInteger();
final AtomicInteger shutdownReadCompleteEventReceivedCounter = new AtomicInteger();
cb.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) {
if (evt == ChannelInputShutdownEvent.INSTANCE) {
shutdownEventReceivedCounter.incrementAndGet();
} else if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
shutdownReadCompleteEventReceivedCounter.incrementAndGet();
ctx.executor().schedule(new Runnable() {
@Override
public void run() {
ctx.close();
}
}, 100, MILLISECONDS);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
serverChannel = sb.bind().sync().channel();
Channel clientChannel = cb.connect(serverChannel.localAddress()).sync().channel();
clientChannel.closeFuture().await();
assertEquals(1, shutdownEventReceivedCounter.get());
assertEquals(1, shutdownReadCompleteEventReceivedCounter.get());
} finally {
if (serverChannel != null) {
serverChannel.close().sync();
}
}
}
use of io.netty.channel.socket.DuplexChannel in project vert.x by eclipse.
the class Http2Test method testDiscardConnectionWhenChannelBecomesInactive.
@Test
public void testDiscardConnectionWhenChannelBecomesInactive() throws Exception {
AtomicInteger count = new AtomicInteger();
server.requestHandler(req -> {
if (count.getAndIncrement() == 0) {
Http2ServerConnection a = (Http2ServerConnection) req.connection();
DuplexChannel channel = (DuplexChannel) a.channel();
channel.shutdown();
} else {
req.response().end();
}
});
startServer(testAddress);
AtomicInteger closed = new AtomicInteger();
client.connectionHandler(conn -> conn.closeHandler(v -> closed.incrementAndGet()));
client.request(requestOptions).onComplete(onSuccess(req -> {
req.send(onFailure(err -> {
}));
}));
AsyncTestBase.assertWaitUntil(() -> closed.get() == 1);
client.request(requestOptions).compose(HttpClientRequest::send).onComplete(onSuccess(resp -> {
testComplete();
}));
await();
}
use of io.netty.channel.socket.DuplexChannel in project netty by netty.
the class SocketHalfClosedTest method testAllDataReadAfterHalfClosure.
private static void testAllDataReadAfterHalfClosure(final boolean autoRead, ServerBootstrap sb, Bootstrap cb) throws Throwable {
final int totalServerBytesWritten = 1024 * 16;
final int numReadsPerReadLoop = 2;
final CountDownLatch serverInitializedLatch = new CountDownLatch(1);
final CountDownLatch clientReadAllDataLatch = new CountDownLatch(1);
final CountDownLatch clientHalfClosedLatch = new CountDownLatch(1);
final AtomicInteger clientReadCompletes = new AtomicInteger();
Channel serverChannel = null;
Channel clientChannel = null;
try {
cb.option(ChannelOption.ALLOW_HALF_CLOSURE, true).option(ChannelOption.AUTO_READ, autoRead).option(ChannelOption.RCVBUF_ALLOCATOR, new TestNumReadsRecvByteBufAllocator(numReadsPerReadLoop));
sb.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = ctx.alloc().buffer(totalServerBytesWritten);
buf.writerIndex(buf.capacity());
ctx.writeAndFlush(buf).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
((DuplexChannel) future.channel()).shutdownOutput();
}
});
serverInitializedLatch.countDown();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
cb.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
private int bytesRead;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf buf = (ByteBuf) msg;
bytesRead += buf.readableBytes();
buf.release();
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt == ChannelInputShutdownEvent.INSTANCE) {
clientHalfClosedLatch.countDown();
} else if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
ctx.close();
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
clientReadCompletes.incrementAndGet();
if (bytesRead == totalServerBytesWritten) {
clientReadAllDataLatch.countDown();
}
if (!autoRead) {
ctx.read();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
serverChannel = sb.bind().sync().channel();
clientChannel = cb.connect(serverChannel.localAddress()).sync().channel();
clientChannel.read();
serverInitializedLatch.await();
clientReadAllDataLatch.await();
clientHalfClosedLatch.await();
assertTrue(totalServerBytesWritten / numReadsPerReadLoop + 10 > clientReadCompletes.get(), "too many read complete events: " + clientReadCompletes.get());
} finally {
if (clientChannel != null) {
clientChannel.close().sync();
}
if (serverChannel != null) {
serverChannel.close().sync();
}
}
}
Aggregations