客户端推送
服务器推送是HTTP/2的一个新特性,此特性使得可以在单一客户端请求中可以并行发出多个响应。推送处理器可以被设置到请求上用来接收服务器推送的请求/响应。
HttpClientRequest request =client.get("/index.html", response -> {
//Process index.html response
});
// Set a push handler to be aware of anyresource pushed by the server
request.pushHandler(pushedRequest -> {
// Aresource is pushed for this request
System.out.println("Server pushed " + pushedRequest.path());
// Setan handler for the response
pushedRequest.handler(pushedResponse -> {
System.out.println("The response for the pushed request");
});
});
// End the request
request.end();
如果客户不想再接收推送的请求,客户端可以重置流:
request.pushHandler(pushedRequest -> {
if(pushedRequest.path().equals("/main.js")) {
pushedRequest.reset();
} else{
//Handle it
}
});
接收定制的HTTP/2帧
HTTP/2是HTTP请求/响应模型中的一多帧的帧协义。协议支持其他帧的发送与接收。为了接收定制帧,可以在请求上使用定制帧处理器(customFrameHandler),当每次定制帧到达时,此处理器将会被调用。例子如下:
response.customFrameHandler(frame -> {
System.out.println("Received a frame type=" + frame.type() +
" payload" +frame.payload().toString());
});
客户端启用压缩
http客户端一起支持的还有HTTP压缩。这表示客户端让远程Http服务器知道此客户端支持压缩,并能处理压缩的响应体。一个http服务器可以自由选择是用支持的压缩算法进行压缩,还是不压缩的方式发回响应体。所以这仅是一个http服务器忽视或使用的提示。为了告知http服务器客户端支持哪种压缩,客户端提供一个支持的压缩算法值作为Accept-Encoding头的值。多个压缩算法被支持的情况,Vert.x将会添加下列头:
Accept-Encoding: gzip, deflate
服务器将选择其中之一。你可以检查服务器是否通过查看响应中的Content-Encoding头压缩了响应体,并发回。
如果响应体通过gzip压缩,响应体将包含下列头:
Content-Encoding: gzip
在创建客户端时设置setTryUseCompression选项启用压缩。默认压缩是禁用的。
HTTP/1.x池化和长连接
Http长连接允许多个请求使用一个连接,在向同一个服务器发送多个请求,这样连接使用就会更有效。对于HTTP/1.x版本,http客户端支持池化连接在请求间重用连接。为了池化,使用setKeepAlive进行请求客户端设置。默认值为true.当KeepAlive启用。Vert.x将会在每个发送的请求中添加Connection:Keep-Alive头。当KeepAlive禁用时,Vert.x在每个发送的请求中添加Connection:Close头,通知服务器在完成响应后连接将会被关闭。对于每个服务器的的连池池的最大连接数通过调用setMaxPoolSize进行设置。在启用池化创建请求时,如果池中的连接数小于最大连接数设置时,Vert.x会创建一个新的连接,否则会将请求添加到等待队列。活动连接不会被客户端自动关闭。为了关闭活动连接,可以关系客户端实例。作为另一种关闭活动连接的选择是用setIdleTimeout设置空闲超时时间,在超时时间内,任何不被使用的连接都会被关闭。请注意空闲时间的单位是秒而不毫秒。
HTTP/1.1管道内嵌
客户端也支持在同一个连接上进行请求内嵌。请求内嵌意思在前一个请求的响应返回前,s可以发送另外请求。管道内嵌不适用于所有请求。为了启用管道内嵌,可以使用setPipelining进行启用。默认pipe-lining是禁用的。在启用客道内嵌后,发送一个请求将不必待前一个响应返回。单一连接上管道内嵌的请求数能过setPipeliningLimit时行限制。这个选项定义了在等待响应时发送http请求的最大数目。这个限制确保了在同一服务器的所有连接上的http请求分布的公平性。
HTTP/2多路复用
HTTP/2主张对一个服务器使用单一连接,默认的http客户端对每个服务器使用单一连接,同一服务器的所有流是多路复用同一个连接。如需要多个连接或者使用池化时,会用到setHttp2MaxPoolSize方法。在每个连接上限制复用流的数量是必须的,同时使用池代替单一连接,这种情况可以用setHttp2MultiplexingLimit。
HttpClientOptions clientOptions = newHttpClientOptions().
setHttp2MultiplexingLimit(10).
setHttp2MaxPoolSize(3);
// Uses up to 3 connections and up to 10 streamsper connection
HttpClient client =vertx.createHttpClient(clientOptions);
单个连接的复用限制设置在客户端上,用于限制每个连接上流也的数量。如果使用SETTINGS_MAX_CONCURRENT_STREAMS 配置设成较低限制,有效值甚至更低。HTTP/2连接不会被客户端自动关闭。为了关闭连接,必须调用客户端实例上的close方法。另一方法是用setIdleTimeout方法设置超时时间-一些在超时时间内不用的连接都将被关闭。请注意超时时间单位是秒而不是毫秒。
HTTP连接
HttpConnection提供了处理HTTP连接事件,生命周期和设置的API。HTTP/2完整实现了HttpConnection的API。HTTP/1.x部分实现了HttpConnection的API:仅是关闭操作,关闭处理器,异常处理器被实现。此协议不提供其他操作的语义。
服务器选项
connection方法反回一个服务器上的请求连接:
HttpConnection connection =request.connection();
在服务器上注册连接处理器获取进行连接时的通知
HttpServer server =vertx.createHttpServer(http2Options);
server.connectionHandler(connection -> {
System.out.println("A client connected");
});
客户端连接
connection方法返回一个客户端连接:
HttpConnection connection =request.connection();
可以在请求上设置连接处理器获取连接通知
request.connectionHandler(connection -> {
System.out.println("Connected to the server");
});
连接设置
HTTP/2使用Http2Settiongs数据对象进行配置。每个端点必须遵守连接另一端发送的配置。在连接建立时,客户端与服务器交换初始设置。使用setInitialSettiongs进行初始设置客户端和服务器。连接建立后,可以在任何时候进行设置:
connection.updateSettings(newHttp2Settings().setMaxConcurrentStreams(100));
在远程端应该确认收到设置更新,可以设置回调确认收到通知:
connection.updateSettings(newHttp2Settings().setMaxConcurrentStreams(100), ar -> {
if(ar.succeeded()) {
System.out.println("The settings update has been acknowledged");
}
});
相反 remoteSettingsHandler在收到远程设置时被调用并获得通知:
connection.remoteSettingsHandler(settings ->{
System.out.println("Received new settings");
});
注释:这仅适用于HTTP/2协议
连接心跳
HTTP/2连接ping在判断连接来回耗时,检查连接有效性上是有用的:ping发送PIBG帧到远程点。
Buffer data = Buffer.buffer();
for (byte i = 0;i < 8;i++) {
data.appendByte(i);
}
connection.ping(data, pong -> {
System.out.println("Remote side replied");
});
在一个PING帧收到之后,Vert.x会自动发送一个确认,使用一个处理器可以处理收到ping的通知:
connection.pingHandler(ping -> {
System.out.println("Got pinged by remote side");
});
处理器会适时被通知,无论确认都会被发回。此特性是针对HTTP/2协义进行的实现。
注意:仅适用于HTTP/2协议。
连接关闭和停止
调用shutdown方法将会发送GOAWAY帧到连接的远程端。请求对方停止创建流:客户端将会停止新建请求并且服务器将停止推送响应。在GOAWAY帖发送之后,连接等待一些时间(默认30秒)直到当前所有流关闭然后关闭连接:
connection.shutdown();
在所有流关闭后,shutdownHandler通知还没有关闭的连接。也有只发送GOAWAY帧的可能,与shutdown的主要区别是,GOAWAY仅告知连接的远程端停止创建新的流还没有流关闭的计划:
connection.goAway(0);
相反,在收到GOAWAY帧时也能被通知:
connection.goAwayHandler(goAway -> {
System.out.println("Received a go away frame");
});
shutdownHandler在当前流关闭和连接关闭时会被调用:
connection.goAway(0);
connection.shutdownHandler(v -> {
// Allstreams are closed, close the connection
connection.close();
});
也适用于在收到GOAWAY帧时。
注意:仅适用于HTTP/2协议
连接关闭
连接的close方法半闭连接:
· close方法半闭HTTP/1.x的socket
· HTTP/2立既关闭,在连接关闭前,GOAWAY帧仍将会发送
在连接被关闭时调用closeHandler。