private void configureSsl(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
// Specify Host in SSLContext New Handler to add TLS SNI Extension
pipeline.addLast(sslCtx.newHandler(ch.alloc(), Http2Client.HOST, Http2Client.PORT));
// We must wait for the handshake to finish and the protocol to be negotiated before configuring
// the HTTP/2 components of the pipeline.
pipeline.addLast(new ApplicationProtocolNegotiationHandler("") {
@Override
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
ChannelPipeline p = ctx.pipeline();
p.addLast(connectionHandler);
configureEndOfPipeline(p);
return;
}
ctx.close();
throw new IllegalStateException("unknown protocol: " + protocol);
}
});
}
可以看出还是熟悉的味道,基于ALPN扩展协商,然后将connectionHandler也就是Http2ConnectionHandler加入pipeline中。
client需要通过http1.1的upgrade header告诉server (值为h2c),进行协议升级,同时通过http2-settings header把HTTP/2 SETTINGS的payload base64url后的值告诉server,这样的设计让client 可以在进行http2通信前告诉server一些参数 ???
server端如果支持http2, 则需要接受upgrade,返回101状态(Swtiching Protocols),在空行后开始传输http2二进制帧数据。
一旦client收到server的101 response,就需要发送connection preface(包括SETTINGS frame)
如果client知道server一定支持http2,那么就可以直接发送connection preface,省去了upgrade这个rtt
这篇博客的侧重点是介绍LoadingCache的设计和实现要点,读完后你会收获
如果你还没有看过LoadingCache的源码,建议先对着代码通读一篇。