用 Netty 发送 HTTP/2 客户端序言
Sending an HTTP/2 client preface with Netty
我正尝试在 Netty 中开始使用 HTTP/2。我试过 "hello world" example,它按预期工作。在示例中,管道看起来像这样:
服务器:
SslHandler
ApplicationProtocolNegotiationHandler
Http2ConnectionHandler
客户:
SslHandler
ApplicationProtocolNegotiationHandler
HttpToHttp2ConnectionHandler
SimpleChannelInboundHandler<Http2Settings>
(在第一个 SETTINGS
帧后从管道中删除)
SimpleChannelInboundHandler<FullHttpResponse>
我正在尝试——主要是出于教育目的——构建一个不进行 HTTP 到 HTTP/2 转换的客户端(即我正在尝试写一些东西 "closer to the metal")。我的服务器看起来几乎与示例服务器完全一样,但我的客户端管道看起来几乎与服务器管道完全一样:
SslHandler
ApplicationProtocolNegotiationHandler
Http2ConnectionHandler
我 运行 遇到的麻烦是客户端序言似乎没有按预期发送:
Dec 02, 2015 9:37:19 PM io.netty.handler.codec.http2.Http2ConnectionHandler processGoAwayWriteResult
SEVERE: Sending GOAWAY failed: lastStreamId '0', errorCode '1', debugData 'HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 000000040000000000'. Forcing shutdown of the connection.
javax.net.ssl.SSLException: SSLEngine closed already
这里要提到的另一件事是,我将直接通过 TLS HTTP/2,而不是尝试进行明文升级。
我已经通读了所有 "hello world" 示例代码和所有基础 类,但我没有看到客户端在示例中将其序言发送到哪里。我怀疑这与示例中的自毁设置处理程序有关,但除了稍后控制非序言流量的时间外,看不到它做了什么。
我也尝试过 Http2ConnectionHandler
Builder
中的 server(boolean)
方法,但没有太大成功。我错过了一些明显的东西吗?我应该如何设置我的客户端管道(或者我应该在设置我的管道后采取什么步骤)来管理序言交换?
或者,发生这种情况的原因可能是客户端试图在序言交换发生之前发送 GOAWAY
(因为我要做的只是连接)。但是,如果是这种情况,那么 "right" 打开连接并保持它打开的方法是什么(如果时间足够长以让序言交换发生)?自毁处理程序是 "expected" 方法吗?
编辑:澄清一下,我不是故意发送 GOAWAY
。如果这就是正在发生的事情,那它本身就是一个谜。
谢谢!
我正在服用疯狂的药丸。使用 .server(false)
构建客户端连接处理程序使一切都按预期工作;我以前试过的时候一定是运行旧代码。为噪音道歉!
编辑:更具体地说,问题似乎是我试图在我的连接处理程序构建器的 build0
方法中执行 .server(false)
。这似乎是不允许的(或者至少是行不通的),但我还不确定为什么。从实际使用构建器的事物调用 .server(false)
得到了预期的结果。
我正尝试在 Netty 中开始使用 HTTP/2。我试过 "hello world" example,它按预期工作。在示例中,管道看起来像这样:
服务器:
SslHandler
ApplicationProtocolNegotiationHandler
Http2ConnectionHandler
客户:
SslHandler
ApplicationProtocolNegotiationHandler
HttpToHttp2ConnectionHandler
SimpleChannelInboundHandler<Http2Settings>
(在第一个SETTINGS
帧后从管道中删除)SimpleChannelInboundHandler<FullHttpResponse>
我正在尝试——主要是出于教育目的——构建一个不进行 HTTP 到 HTTP/2 转换的客户端(即我正在尝试写一些东西 "closer to the metal")。我的服务器看起来几乎与示例服务器完全一样,但我的客户端管道看起来几乎与服务器管道完全一样:
SslHandler
ApplicationProtocolNegotiationHandler
Http2ConnectionHandler
我 运行 遇到的麻烦是客户端序言似乎没有按预期发送:
Dec 02, 2015 9:37:19 PM io.netty.handler.codec.http2.Http2ConnectionHandler processGoAwayWriteResult
SEVERE: Sending GOAWAY failed: lastStreamId '0', errorCode '1', debugData 'HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 000000040000000000'. Forcing shutdown of the connection.
javax.net.ssl.SSLException: SSLEngine closed already
这里要提到的另一件事是,我将直接通过 TLS HTTP/2,而不是尝试进行明文升级。
我已经通读了所有 "hello world" 示例代码和所有基础 类,但我没有看到客户端在示例中将其序言发送到哪里。我怀疑这与示例中的自毁设置处理程序有关,但除了稍后控制非序言流量的时间外,看不到它做了什么。
我也尝试过 Http2ConnectionHandler
Builder
中的 server(boolean)
方法,但没有太大成功。我错过了一些明显的东西吗?我应该如何设置我的客户端管道(或者我应该在设置我的管道后采取什么步骤)来管理序言交换?
或者,发生这种情况的原因可能是客户端试图在序言交换发生之前发送 GOAWAY
(因为我要做的只是连接)。但是,如果是这种情况,那么 "right" 打开连接并保持它打开的方法是什么(如果时间足够长以让序言交换发生)?自毁处理程序是 "expected" 方法吗?
编辑:澄清一下,我不是故意发送 GOAWAY
。如果这就是正在发生的事情,那它本身就是一个谜。
谢谢!
我正在服用疯狂的药丸。使用 .server(false)
构建客户端连接处理程序使一切都按预期工作;我以前试过的时候一定是运行旧代码。为噪音道歉!
编辑:更具体地说,问题似乎是我试图在我的连接处理程序构建器的 build0
方法中执行 .server(false)
。这似乎是不允许的(或者至少是行不通的),但我还不确定为什么。从实际使用构建器的事物调用 .server(false)
得到了预期的结果。