Netty啟動對HTTP/3的孵化器支援
經過一個多月的開發,我們終於可以釋出我們的第一個孵化器版本Netty / Incubator / Codec / Quic。
為了能夠在不“影響”網路核心的情況下開發令人興奮的新功能,我們決定在“孵化器”中開始開發此類功能。這意味著這些功能將在單獨的儲存庫中開發,並且只有在我們可以保證不再需要破壞API並考慮將這些產品準備就緒後,才會合併回核心netty儲存庫。這有望有助於澄清程式碼的期望和穩定性,因此人們應該充分意識到API可能會發生變化。除此之外,它還允許使用不同的釋出時間表。
您需要為您的平臺包括正確的依賴項。目前,我們僅支援macOS x86_64或linux x86_64。也就是說,這種情況將來可能會改變。
Maven / Linux的示例為:
<dependency> <groupId>io.netty.incubator</groupId> <artifactId>netty-incubator-codec-quic</artifactId> <version>0.0.1.Final</version> <classifier>linux-x86_64</classifier> </dependency> |
或者,如果您使用macOS:
<dependency> <groupId>io.netty.incubator</groupId> <artifactId>netty-incubator-codec-quic</artifactId> <version>0.0.1.Final</version> <classifier>osx-x86_64</classifier> </dependency> |
如何設定QUIC伺服器/客戶端?
// 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); ChannelHandler codec = new QuicServerCodecBuilder() .certificateChain("./src/test/resources/cert.crt") .privateKey("./src/test/resources/cert.key") .applicationProtocols(proto) .maxIdleTimeout(5000, TimeUnit.MILLISECONDS) // Configure some limits for the maximal number of streams (and the data) that we want to handle. .initialMaxData(10000000) .initialMaxStreamDataBidirectionalLocal(1000000) .initialMaxStreamDataBidirectionalRemote(1000000) .initialMaxStreamsBidirectional(100) .initialMaxStreamsUnidirectional(100) // Setup a token handler. In a production system you would want to implement and provide your // custom one. .tokenHandler(InsecureQuicTokenHandler.INSTANCE) // ChannelHandler that is added into QuicChannel pipeline. .handler(new ChannelInboundHandlerAdapter() { @Override public void channelActive(ChannelHandlerContext ctx) { QuicChannel channel = (QuicChannel) ctx.channel(); // Create streams etc.. } public void channelInactive(ChannelHandlerContext ctx) { ((QuicChannel) ctx.channel()).collectStats().addListener(f -> { if (f.isSuccess()) { LOGGER.info("Connection closed: {}", f.getNow()); } }); } @Override public boolean isSharable() { return true; } }) .streamHandler(new ChannelInitializer<QuicStreamChannel>() { @Override protected void initChannel(QuicStreamChannel ch) { // Add a LineBasedFrameDecoder here as we just want to do some simple HTTP 0.9 handling. ch.pipeline().addLast(new LineBasedFrameDecoder(1024)) .addLast(new ChannelInboundHandlerAdapter() { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; try { if (byteBuf.toString(CharsetUtil.US_ASCII).trim().equals("GET /")) { ByteBuf buffer = ctx.alloc().directBuffer(); buffer.writeCharSequence("Hello World!\r\n", CharsetUtil.US_ASCII); // Write the buffer and shutdown the output by writing a FIN. ctx.writeAndFlush(buffer).addListener(QuicStreamChannel.SHUTDOWN_OUTPUT); } } finally { byteBuf.release(); } } }); } }).build(); try { Bootstrap bs = new Bootstrap(); Channel channel = bs.group(group) .channel(NioDatagramChannel.class) .handler(codec) .bind(new InetSocketAddress(9999)).sync().channel(); channel.closeFuture().sync(); } finally { group.shutdownGracefully(); } |
QUIC客戶端:
// 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(); } |
專案本身位於GitHub上。
相關文章
- 支援Http3和Quic協議的Netty孵化器版本釋出HTTPUI協議Netty
- netty系列之:netty對SOCKS協議的支援Netty協議
- netty系列之:netty對marshalling的支援Netty
- netty系列之:讓TLS支援http2NettyTLSHTTP
- netty系列之:使用netty實現支援http2的伺服器NettyHTTP伺服器
- netty系列之:netty對http2訊息的封裝NettyHTTP封裝
- Google Chrome 將增加對 HTTP Exchanges 的支援GoChromeHTTP
- Netty的wss支援Netty
- Ubuntu 20.04.6 LTS釋出,啟用對安全啟動系統的支援Ubuntu
- MyBatis對動態SQL的支援MyBatisSQL
- 深入淺出Netty:服務啟動Netty
- Netty啟動流程及原始碼分析Netty原始碼
- 如何實現IIS 7.0對非HTTP協議的支援HTTP協議
- netty系列之:netty實現http2中的流控制NettyHTTP
- Netty學習筆記(五)NioEventLoop啟動Netty筆記OOP
- Netty NioEventLoop 啟動過程原始碼分析NettyOOP原始碼
- python 啟動http服務PythonHTTP
- Netty 框架學習 —— 基於 Netty 的 HTTP/HTTPS 應用程式Netty框架HTTP
- Netty原始碼分析(三):客戶端啟動Netty原始碼客戶端
- Netty原始碼分析(二):服務端啟動Netty原始碼服務端
- tomcat中開啟的對SSL(https)的支援TomcatHTTP
- POP3對Folder操作不支援??
- node.js啟動http服務Node.jsHTTP
- netty系列之:自建客戶端和HTTP伺服器互動Netty客戶端HTTP伺服器
- Netty系列文章之服務端啟動分析Netty服務端
- Netty原始碼解析 -- 服務端啟動過程Netty原始碼服務端
- Netty 框架學習 —— 新增 WebSocket 支援Netty框架Web
- netty寫一個http伺服器NettyHTTP伺服器
- IE9對CSS3的支援情況概述IE9CSSS3
- netty原始碼分析之服務端啟動全解析Netty原始碼服務端
- Java9系列第九篇-對HTTP2協議的支援與非阻塞HTTP-APIJavaHTTP協議API
- Netty 實現HTTP檔案伺服器NettyHTTP伺服器
- 啟動64位 IIS 32位應用程式的支援
- Python 臨時啟動簡單的 HTTP 伺服器PythonHTTP伺服器
- Netty服務端啟動過程相關原始碼分析Netty服務端原始碼
- Netty入門系列(3) --使用Netty進行編解碼的操作Netty
- iOS - Swift快速整合啟動頁廣告,支援GIF,支援本地圖片iOSSwift地圖
- 彗星HTTP操作支援庫 - 易語言支援庫HTTP