use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.
the class HttpServerUpgradeHandlerTest method upgradesPipelineInSameMethodInvocation.
@Test
public void upgradesPipelineInSameMethodInvocation() {
final HttpServerCodec httpServerCodec = new HttpServerCodec();
final UpgradeCodecFactory factory = new UpgradeCodecFactory() {
@Override
public UpgradeCodec newUpgradeCodec(CharSequence protocol) {
return new TestUpgradeCodec();
}
};
ChannelHandler testInStackFrame = new ChannelDuplexHandler() {
// marker boolean to signal that we're in the `channelRead` method
private boolean inReadCall;
private boolean writeUpgradeMessage;
private boolean writeFlushed;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
assertFalse(inReadCall);
assertFalse(writeUpgradeMessage);
inReadCall = true;
try {
super.channelRead(ctx, msg);
// All in the same call stack, the upgrade codec should receive the message,
// written the upgrade response, and upgraded the pipeline.
assertTrue(writeUpgradeMessage);
assertFalse(writeFlushed);
assertNull(ctx.pipeline().get(HttpServerCodec.class));
assertNotNull(ctx.pipeline().get("marker"));
} finally {
inReadCall = false;
}
}
@Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
// We ensure that we're in the read call and defer the write so we can
// make sure the pipeline was reformed irrespective of the flush completing.
assertTrue(inReadCall);
writeUpgradeMessage = true;
ctx.channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
ctx.write(msg, promise);
}
});
promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
writeFlushed = true;
}
});
}
};
HttpServerUpgradeHandler upgradeHandler = new HttpServerUpgradeHandler(httpServerCodec, factory);
EmbeddedChannel channel = new EmbeddedChannel(testInStackFrame, httpServerCodec, upgradeHandler);
String upgradeString = "GET / HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Upgrade, HTTP2-Settings\r\n" + "Upgrade: nextprotocol\r\n" + "HTTP2-Settings: AAMAAABkAAQAAP__\r\n\r\n";
ByteBuf upgrade = Unpooled.copiedBuffer(upgradeString, CharsetUtil.US_ASCII);
assertFalse(channel.writeInbound(upgrade));
assertNull(channel.pipeline().get(HttpServerCodec.class));
assertNotNull(channel.pipeline().get("marker"));
channel.flushOutbound();
ByteBuf upgradeMessage = channel.readOutbound();
String expectedHttpResponse = "HTTP/1.1 101 Switching Protocols\r\n" + "connection: upgrade\r\n" + "upgrade: nextprotocol\r\n\r\n";
assertEquals(expectedHttpResponse, upgradeMessage.toString(CharsetUtil.US_ASCII));
assertTrue(upgradeMessage.release());
assertFalse(channel.finishAndReleaseAll());
}
use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.
the class HexDumpProxyFrontendHandler method channelActive.
@Override
public void channelActive(ChannelHandlerContext ctx) {
final Channel inboundChannel = ctx.channel();
// Start the connection attempt.
Bootstrap b = new Bootstrap();
b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass()).handler(new HexDumpProxyBackendHandler(inboundChannel)).option(ChannelOption.AUTO_READ, false);
ChannelFuture f = b.connect(remoteHost, remotePort);
outboundChannel = f.channel();
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
// connection complete start to read first data
inboundChannel.read();
} else {
// Close the connection if the connection attempt has failed.
inboundChannel.close();
}
}
});
}
use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.
the class StompWebSocketChatServer method start.
public void start(final int port) throws Exception {
NioEventLoopGroup boosGroup = new NioEventLoopGroup(1);
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap().group(boosGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new StompWebSocketChatServerInitializer("/chat"));
bootstrap.bind(port).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
System.out.println("Open your web browser and navigate to http://127.0.0.1:" + PORT + '/');
} else {
System.out.println("Cannot start server, follows exception " + future.cause());
}
}
}).channel().closeFuture().sync();
} finally {
boosGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.
the class StompChatHandler method onSubscribe.
private void onSubscribe(ChannelHandlerContext ctx, StompFrame inboundFrame) {
String destination = inboundFrame.headers().getAsString(DESTINATION);
String subscriptionId = inboundFrame.headers().getAsString(ID);
if (destination == null || subscriptionId == null) {
sendErrorFrame("missed header", "Required 'destination' or 'id' header missed", ctx);
return;
}
Set<StompSubscription> subscriptions = chatDestinations.get(destination);
if (subscriptions == null) {
subscriptions = new HashSet<StompSubscription>();
Set<StompSubscription> previousSubscriptions = chatDestinations.putIfAbsent(destination, subscriptions);
if (previousSubscriptions != null) {
subscriptions = previousSubscriptions;
}
}
final StompSubscription subscription = new StompSubscription(subscriptionId, destination, ctx.channel());
if (subscriptions.contains(subscription)) {
sendErrorFrame("duplicate subscription", "Received duplicate subscription id=" + subscriptionId, ctx);
return;
}
subscriptions.add(subscription);
ctx.channel().closeFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
chatDestinations.get(subscription.destination()).remove(subscription);
}
});
String receiptId = inboundFrame.headers().getAsString(RECEIPT);
if (receiptId != null) {
StompFrame receiptFrame = new DefaultStompFrame(StompCommand.RECEIPT);
receiptFrame.headers().set(RECEIPT_ID, receiptId);
ctx.writeAndFlush(receiptFrame);
}
}
use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.
the class LocalChannelTest method testWriteInWritePromiseCompletePreservesOrder.
@Test
public void testWriteInWritePromiseCompletePreservesOrder() throws InterruptedException {
Bootstrap cb = new Bootstrap();
ServerBootstrap sb = new ServerBootstrap();
final CountDownLatch messageLatch = new CountDownLatch(2);
final ByteBuf data = Unpooled.wrappedBuffer(new byte[1024]);
final ByteBuf data2 = Unpooled.wrappedBuffer(new byte[512]);
try {
cb.group(group1).channel(LocalChannel.class).handler(new TestHandler());
sb.group(group2).channel(LocalServerChannel.class).childHandler(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
final long count = messageLatch.getCount();
if ((data.equals(msg) && count == 2) || (data2.equals(msg) && count == 1)) {
ReferenceCountUtil.safeRelease(msg);
messageLatch.countDown();
} else {
super.channelRead(ctx, msg);
}
}
});
Channel sc = null;
Channel cc = null;
try {
// Start server
sc = sb.bind(TEST_ADDRESS).syncUninterruptibly().channel();
// Connect to the server
cc = cb.connect(sc.localAddress()).syncUninterruptibly().channel();
final Channel ccCpy = cc;
// Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() {
@Override
public void run() {
ChannelPromise promise = ccCpy.newPromise();
promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
ccCpy.writeAndFlush(data2.retainedDuplicate(), ccCpy.newPromise());
}
});
ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
}
});
assertTrue(messageLatch.await(5, SECONDS));
} finally {
closeChannel(cc);
closeChannel(sc);
}
} finally {
data.release();
data2.release();
}
}
Aggregations