1 http2 是什么?
http2 可以把多个传统的http 的请求合并在同一个tcp连接中,减少了并发连接请求数, 为了实现这一目标,所以http2中引入了stream的概念
2 http2 中 stream概念理解
一般地说,一个传统的http request/response就对应一个stream, 每一个stream在同一个tcp连接中会有唯一的一个id, 如果是由客户端主动生成的则为奇数,由服务端生成的则为偶数。一般地,服务端有同时并发stream请求处理数的限制(正在处理尚未结束的stream)。
代表每一个标准的http1 请求的stream均由Header Frame(头部帧)与Data Frame(数据帧),其中Header Frame相当于http1协议中的头,一个stream中只能有一个Header,Data Frame 相当http1中body体,可以有多个,每帧的数据大小有限制,协议中可以双方协商(http2 settings),超过大小需要分成多个帧来发送。对于大多数客户端的处理框架来说,需要接收完所有数据帧才算得到一个完整的响应。(这点对于想模拟aws alexa智能终端时有点坑(它有个download channel),需要自己处理,费劲)
3 stream关键状态
每一个stream都对应有远端关闭与否,本地关闭与否 几种组合状态,具体状态转换迁移可见相关协议文档。
一般地,本地向远端发送一个标记为结束状态的帧时,则本地会进入结束状态,本地将无法再向远端发送数据,只能接收远端数据(远端非关闭时)。当收到一个远程结束状态的帧时,则远程进入关闭状态,本地不再接收远端数据。
4 http2中Frame 概念
http2中,Frame是一个最基本的数据发送单元(可理解为最小的数据单位,在stream里发送/接收任何数据都是以帧单位进行的)。帧由头部(固定长度,9字节)与帧体(可变长度,由帧头标记(占3字节,24bit表示)),每个stream可以发送一个或多个帧。
帧的类别有:
DATA 0x0
HEADERS 0x1
PRIORITY 0x2
RST_STREAM 0x3
SETTINGS 0x4
PUSH_PROMISE 0x5
PING 0x6
GOAWAY 0x7
WINDOW_UPDATE 0x8
CONTINUATION 0x9
更详细的参见协议
5 http1 与http2的协商
从协议上说,http1与http2是不同的,为了兼容,需要双方有一个确认支持的过程。
支持2.0的客户端在发起http 1请求时,头部会增加一个升级参数标记(Upgrade: h2c)
支持http 2 的服务器识别到该参数时,会给出一个升级响应:
HTTP/1.1 100 Switching Protocols
Connection: Upgrade
Upgrade: h2c
从而完成整个协议的升级,如果不支持http 2.0 则忽略掉该字段,以http 1.1响应
6 AVS 中 Downoad Channel概念
在AWS AVS协议中,智能音箱终端首次与服务器建立连接时第一件事就是建立download channel, 其实就是终端连接成功后,马上创建一个stream,通过它发送一个结束状态的http2 header 帧,(类似于Http1 Get : /directives 请求),之后该stream进入本地关闭状态,只接收服务端发送过来的数据。
在服务端收到这个请求数据后,应该返回一个multipart的响应头信息(http2 header帧),之后就只需要发送data frame了。 需要注意的是,通过这个stream发送的帧数据状态都只能为非结束状态,否则终端只能关闭整个连接重新连接服务器。
7 目前支持的http 2.0的JAVA方面的库有
1 OKHttpClient (作为客户端调用)
2 Netty http 2.0 (非常适合http 2.0服务器方面的实现)