netty系列之:netty对http2消息的封装
文章目录
- 简介
- http2消息的结构
- netty对http2的封装
- Http2Stream
- Http2Frame
- 总结
简介
无论是什么协议,如果要真正被使用的话,需要将该协议转换成为对应的语言才好真正的进行应用,本文将从http2消息的结构出发,探讨一下netty对http2消息的封装,带大家领略一下真正的框架应该做到什么程度。
http2消息的结构
http2和http1.1不同的是它使用了新的二进制分帧,通过客户端和服务器端建立数据流steam来进行客户端和服务器端之间消息的交互。其中数据流是一个双向字节流,用来发送一条或者多条消息。
消息是客户端和服务端发送的一个逻辑上完整的数据。根据数据大小的不同,可以将消息划分为不同的帧Frame。也就是说message是由不同的frame组成的。
frame就是http2中进行通信的最小单位,根据上一节的介绍,我们知道frame有这样几种:
- DATA frame
- HEADERS frame
- PRIORITY frame
- RST_STREAM frame
- SETTINGS acknowledgment frame
- SETTINGS frame
- PING frame
- PING acknowledgment
- PUSH_PROMISE frame
- GO_AWAY frame
- WINDOW_UPDATE frame
- Unknown Frame
我们看一下http2中stream和frame的一个大体的结构:
在http2中,一个TCP连接,可以承载多个数据流stream,多个stream中的不同frame可以交错发送。
每个frame通过stream id来标记其所属的stream。
有了上面的http2的基本概念,我们接下来就看下netty对http2的封装了。
netty对http2的封装
Http2Stream
作为一个TCP连接下面的最大的单位stream,netty中提供了接口Http2Stream。注意,Http2Stream是一个接口,它有两个实现类,分别是DefaultStream和ConnectionStream。
Http2Stream中有两个非常重要的属性,分别是id和state。
id前面已经介绍了,是stream的唯一标记。这里要注意由客户端建立的 Stream ID 必须是奇数,而由服务端建立的 Stream ID 必须是偶数。另外Stream ID 为 0 的流有特殊的作用,它是CONNECTION_STREAM_ID,1 表示HTTP_UPGRADE_STREAM_ID。
state表示stream的状态,具体而言,stream有下面几个状态:
IDLE(false, false),RESERVED_LOCAL(false, false),RESERVED_REMOTE(false, false),OPEN(true, true),HALF_CLOSED_LOCAL(false, true),HALF_CLOSED_REMOTE(true, false),CLOSED(false, false);
为什么状态需要区分local和remote呢?这是因为stream连接的两端,所以有两端的状态。
和stream状态相对应的就是http2的生命周期了。netty提供了Http2LifecycleManager来表示对http2生命周期的管理:
void closeStreamLocal(Http2Stream stream, ChannelFuture future);void closeStreamRemote(Http2Stream stream, ChannelFuture future);void closeStream(Http2Stream stream, ChannelFuture future);ChannelFuture resetStream(ChannelHandlerContext ctx, int streamId, long errorCode,ChannelPromise promise);ChannelFuture goAway(ChannelHandlerContext ctx, int lastStreamId, long errorCode,ByteBuf debugData, ChannelPromise promise);void onError(ChannelHandlerContext ctx, boolean outbound, Throwable cause);
分别是关闭stream,重置stream,拒绝新建stream:goAway,和处理出错状态这几种。
Http2Frame
stream之后,就是真实承载http2消息的Http2Frame了。在netty中,Http2Frame是一个接口,它有很多具体的实现。
Http2Frame的直接子类包括HTTP2GoAwayFrame、HTTPPingFrame、Http2SettingsFrame和HTTP2SettingsAckFrame。
其中goAway表示不接受新的stream,ping用来进行心跳检测。SETTINGS用来修改连接或者 Stream 流的配置。
netty中专门有一个Http2Settings类和其对应。
在这个类中定义了一些特别的setting名字:
SETTINGS 名字 | 含义 |
---|---|
SETTINGS_HEADER_TABLE_SIZE | 对端索引表的最大尺寸 |
SETTINGS_ENABLE_PUSH | 是否启用服务器推送功能 |
SETTINGS_MAX_CONCURRENT_STREAMS | 接收端允许的最大并发 Stream 数量 |
SETTINGS_INITIAL_WINDOW_SIZE | 发送端的窗口大小,用于 Stream 级别流控 |
SETTINGS_MAX_FRAME_SIZE | 设置帧的最大大小 |
SETTINGS_MAX_HEADER_LIST_SIZE | 对端头部索引表的最大尺寸 |
除了上面讲的4个frame之外,其他的frame实现都继承自Http2StreamFrame,具体而言有PriorityFrame,ResetFrame,HeadersFrame,DataFrame,WindowUpdateFrame,PushPromiseFrame和UnknownFrame。
各个frame分别代表了不同的功能。这里最重要的就是Http2HeadersFrame和Http2DataFrame。
Http2HeadersFrame主要是客户端发送给服务器端的http2请求。
具体而言除了标准的http1.1的header之外,http2还支持下面的header:
METHOD(":method", true),SCHEME(":scheme", true),AUTHORITY(":authority", true),PATH(":path", true),STATUS(":status", false),PROTOCOL(":protocol", true);
对于Http2DataFrame来说,他本身是一个ByteBufHolder,用来传递具体的数据信息。data frame的Payload直接存储在ByteBuf中。
总结
以上就是netty对http2消息的封装了。
本文的例子可以参考:learn-netty4
本文已收录于 http://www.flydean.com/28-netty-wrap-http2/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
netty系列之:netty对http2消息的封装相关推荐
- 【读后感】Netty 系列之 Netty 高性能之道 - 相比 Mina 如何 ?
[读后感]Netty 系列之 Netty 高性能之道 - 相比 Mina 如何 ? 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...
- netty系列之:netty实现http2中的流控制
文章目录 简介 http2中的流控制 netty对http2流控制的封装 Http2FlowController Http2LocalFlowController Http2RemoteFlowCon ...
- netty系列之:netty架构概述
文章目录 简介 netty架构图 丰富的Buffer数据机构 零拷贝 统一的API 事件驱动 其他优秀的特性 总结 简介 Netty为什么这么优秀,它在JDK本身的NIO基础上又做了什么改进呢?它的架 ...
- netty系列之:netty初探
文章目录 简介 netty介绍 netty的第一个服务器 netty的第一个客户端 运行服务器和客户端 总结 简介 我们常用浏览器来访问web页面得到相关的信息,通常来说使用的都是HTTP或者HTTP ...
- Netty系列之Netty基础概念与组件
什么是Netty,Netty各个组件介绍 本部分转载自 Java技术债务[什么是Netty?为什么使用Netty?Netty有哪些组件?] 原文链接:https://blog.csdn.net/qq_ ...
- Netty系列之Netty线程模型
关注点在于:如何灵活的动态绑定IO事件处理,又能进行串行化处理减少锁的使用 摘自:http://www.infoq.com/cn/articles/netty-threading-model 1. 背 ...
- Netty系列之Netty编解码框架分析
1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decod ...
- 【Netty系列】Netty百万级推送服务设计要点
一. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- Netty系列之Netty百万级推送服务设计要点
原文来自于:李林峰 https://www.infoq.cn/article/netty-million-level-push-service-design-points/ 1. 背景 1.1. 话题 ...
最新文章
- python字符串用android,通过s从android客户端向python服务器发送字符串
- 重温名篇《康托尔、哥德尔、图灵——永恒的金色对角线》
- mysql 定时器停止_mysql事件【定时器】
- 沫沫金Echarts移动端demo
- python 决策树 math库 c45算法
- nginx负载均衡的5种策略
- 412.数组下标的倍数 Fizz Buzz
- Linux下 PHP 安装ioncube扩展
- 天堂2 服务器修改,服务器技术交流_新天堂2-战乱的序幕架设教程_-921根据地_只做有质量的游戏 - Powered by Discuz!...
- arcgis制作遥感影像标签(分割分类目标提取方向)
- 会员(用户)数据化运营——指标介绍
- 护眼html颜色,在电脑中设置护眼颜色、更换网页背景色、一键护眼
- 工商管理硕士(MBA)提前面试案例与技巧
- 如何测试服务器端口是否打开?
- 语句摘抄——第13周
- 【Arduino实验08 红外传感器】
- 果然,ChatGPT 还是被拿去搞黄色了...
- Java架构师成长之道之Java架构师技术栈
- 数据结构:元祖、列表、字典、集合概念及区别
- Android 第二春 无缝Harmony 开发