// We just want to support HTTP 0.9 as application protocol byte[] proto = new byte[] { 0x08, 'h', 't', 't', 'p', '/', '0', '.', '9' };
NioEventLoopGroup group = new NioEventLoopGroup(1); try { ChannelHandler codec = new QuicClientCodecBuilder() .applicationProtocols(proto) .maxIdleTimeout(5000, TimeUnit.MILLISECONDS) .initialMaxData(10000000) // As we don't want to support remote initiated streams just setup the limit for // local initiated streams in this example. .initialMaxStreamDataBidirectionalLocal(1000000) .build();
Bootstrap bs = new Bootstrap(); Channel channel = bs.group(group) .channel(NioDatagramChannel.class) .handler(codec) .bind(0).sync().channel();
QuicChannel quicChannel = QuicChannel.newBootstrap(channel) .streamHandler(new ChannelInboundHandlerAdapter() { @Override public void channelActive(ChannelHandlerContext ctx) { // As we did not allow any remote initiated streams we will never see // this method called. That said just let us keep it here to demonstrate // that this handle would be called for each remote initiated stream. ctx.close(); } }) .remoteAddress(new InetSocketAddress(NetUtil.LOCALHOST4, 9999)) .connect() .get();
QuicStreamChannel streamChannel = quicChannel.createStream(QuicStreamType.BIDIRECTIONAL, new ChannelInboundHandlerAdapter() { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; System.err.println(byteBuf.toString(CharsetUtil.US_ASCII)); byteBuf.release(); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt == ChannelInputShutdownReadComplete.INSTANCE) { // Close the connection once the remote peer did send the FIN // for this stream. ((QuicChannel) ctx.channel().parent()).close(true, 0, ctx.alloc().directBuffer(16) .writeBytes(new byte[]{'k', 't', 'h', 'x', 'b', 'y', 'e'})); } } }).sync().getNow(); // Write the data and send the FIN. After this its not possible anymore to write any more data. streamChannel.writeAndFlush(Unpooled.copiedBuffer("GET /\r\n", CharsetUtil.US_ASCII)) .addListener(QuicStreamChannel.SHUTDOWN_OUTPUT);
// Wait for the stream channel and quic channel to be closed (this will happen after we // received the FIN). After this is done we will close the underlying datagram channel. streamChannel.closeFuture().sync(); quicChannel.closeFuture().sync(); channel.close().sync(); } finally { group.shutdownGracefully(); }
|