HTTP2和WebSocket
HTTP
http是目前应用最广泛的应用层协议,截止到目前为止已经发布了多个版本,最常用的是http1.1和http2。
http0.9是最早的版本,功能很简单,没有header,只支持GET。
http1.0
只支持短连接,即每次请求一个资源就会新建一次tcp连接,服务器写完响应行后立刻将TCP连接关闭
由于tcp连接的建立和关闭需要经历三次握手和四次握手,再加上tcp慢启动特性,报文一开始不会满负荷传输,所以不仅开销很大,而且效率很低。
相比于上一版本,增加了http header,和status code用于声明请求的结果,content-type字段也可以用来声明传输其他文件,头部还增加了协议的版本号。
http1.1是1997年发布的,是现在使用最广泛的版本,这个版本引入了长连接,减少了tcp连接建立和关闭的消耗。
新加了connection请求头字段,false表示短连接,keep-alive表示长连接(默认)
在持久连接模式中,由于服务器不会立刻关闭TCP连接,所以需要在响应中加上一个
Content-Length
的响应头来表示响应体的长度,让浏览器判断HTTP响应是否结束。如果没有这个响应头的话,浏览器会处于pending
的状态,因为在它看来还有数据要接收。所以长连接无非就是通过Content-Length字段把连接关闭的主动权交给了客户端。
支持分块传输编码,可以发送动态数据,只在1.1版本中可以使用
使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小,使得服务器可以发送动态生成的数据。
设置相应头Transfer-Encoding:chunked,此时消息体便由数量未定的块组成,并以最后一个大小为0的块结束。
HTTP/1.1 200 OK\r\n
\r\n
Transfer-Encoding: chunked\r\n
...\r\n
\r\n
<chunked 1 length>\r\n
<chunked 1 content>\r\n
<chunked 2 length>\r\n
<chunked 2 content>\r\n
...\r\n
0\r\n
\r\n
\r\n
其他的改变还有增加了Host头,让服务端知道用户请求的是哪个域名等。
2014年,更新了内容,增加了TLS支持,即https传输,除了短连接和长连接模型,还支持服务端push模型,websocket模型。
Http2是2015年发布的,主要就是提升安全性与性能,gRPC底层就是使用的http2协议。
多路复用(Multiplexing):就是说 HTTP/2 可以重复使用同一个 TCP 连接,并且连接是多路的,多个请求或响应可以同时传输,这也是gRPC支持客户端流和服务器端流的原因
对比之下,HTTP/1.1 的长连接也能复用 TCP 连接,但是只能串行,不能“多路”。
Rest API通常构建在http1.1上,是请求响应模式。如果一个微服务收到多个客户端请求,每次只能处理一个,即使构建在http2上,依旧是请求响应模式,无法发挥http2的优势:多路复用。
gRPC构建在http2上,支持流式通信和双向通信,通过不断流式传输信息同时处理这些请求。但双向流模式依旧需要客户端发起调用。这里的流式通信,不是全双工的,只是将原本的请求响应风格,变为了同时可以发送多个请求,服务器也能发送多个响应。
二进制协议:HTTP/2 的消息头使用二进制格式,而非文本格式。并且使用专门设计的 HPack 算法压缩。
服务器推送:服务端能够直接把资源推送给客户端,当客户端需要这些文件的时候,它已经在客户端了。(HTTP/2推送服务器只能被浏览器来处理,而不是应用)
通讯双方cache一份header filed表,用来差量更新头部字段,避免重复header的传输
HTTP3
2018年发布,基于谷歌的QUIC,底层使用udp代码tcp协议,
这样解决了队头阻塞问题,同样无需握手,性能大大地提升,默认使用tls加密。
WebSocket
websocket是一个双向通信协议,它在握手阶段采用http1.1
握手过程
发起握手请求
HTTP/1.1 101 Switching Protocols // 状态行
Upgrade: websocket // required
Connection: Upgrade // required
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // required,加密后的 Sec-WebSocket-Key
Sec-WebSocket-Protocol: chat // 表明选择的子协议
服务器如果支持websocket,返回101响应
HTTP/1.1 101 Switching Protocols // 状态行
Upgrade: websocket // required
Connection: Upgrade // required
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // required,加密后的 Sec-WebSocket-Key
Sec-WebSocket-Protocol: chat // 表明选择的子协议
WebSocket 提供两种协议:不加密的 ws://
和 加密的 wss://
. 因为是用 HTTP 握手,它和 HTTP 使用同样的端口:ws 是 80(HTTP),wss 是 443(HTTPS)
HTTP2 vs WebSocket
WebSocket是全双工的,可以双向通信,主要应用在实时通信的场景中,服务器可以实时推送数据给客户端。
HTTP/2 虽然也支持 Server Push,但是服务器只能主动将资源推送到客户端缓存!那不是应用程序可以感知的,主要是让浏览器(用户代理)提前缓存静态资源。
在典型的HTTP 1.x工作流中,浏览器请求一个页面,服务器在响应中返回一个HTML,然后就时等待浏览器解析响应并发送额外请求来获取额外的内嵌资源(JavaScript、CSS等)。服务器推送使服务器能够试探性地向客户端发送资源。此时,浏览器不必解析HTML页面并找到需要加载的其它资源;而是服务器能够立即开始发送它们。
但是人类的想象力是非常丰富的。比如为了让服务器可以推送消息给客户端,使用了一个“偏方”。它就是SSE(Server Sent Event)。SSE是一种让服务器能够在客户端服务器建立连接之后异步推送数据给客户端的机制。由于SSE是基于HTTP的,其天然适配于HTTP/2,这样SSE就可以集两者之长:HTTP/2可以基于多路复用流形成一个高效传输层,同时SSE给应用提供了API使之能够进行推送。
Websocket技术可能会继续使用,但是SSE和其EventSource API同HTTP/2的能力相结合可以在多数场景下达到同样的效果,但是会更简单。
HTTP2和WebSocket的更多相关文章
- Android okHttp网络请求之Get/Post请求
前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...
- Android网络框架比较
今天,公司需要为一个安卓app选择一个合适的网络框架,具体我了解,主要的安卓网络框架有okhttp,retrofit,android-async-http,volley. 查找网上的资料,大致可以得到 ...
- Jetty 9.3庆祝20周年生日快乐,并添加HTTP/2支持
本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2015/06/Building-Distributed-Systems 今年6月12日 ...
- channels 2.x的使用
转载:https://www.vimiix.com/post/2018/07/26/channels2-tutorial/ 认识 Channels 之前,需要先了解一下 asgi ,全名:Asynch ...
- [转载]前端 阿里p6面试题集锦含答案
1.说一下你了解CSS盒模型. 盒模型分为:IE的怪异盒模型和标注浏览器的盒模型,然后可以通过box-sizing属性控制两种盒模型的变换. 2.说一下box-sizing的应用场景. 这个也不难,简 ...
- 3月web前端面试小结
说一下box-sizing的应用场景 box-sizing的属性值分为两个,border-box和content-box,其中, border-box:width=content+padding+bo ...
- jdk11新特性
JDK 11主要特性一览 jdk11即将在9月25号发布正式版.确定的新特性包括以下17个 181 嵌套类可见性控制 309 动态文件常量 315 改进 Aarch64 Intrinsics 318 ...
- 详解golang net之transport
关于golang http transport的讲解,网上有很多文章读它进行了描述,但很多文章讲的都比较粗,很多代码实现并没有讲清楚.故给出更加详细的实现说明.整体看下来细节实现层面还是比较难懂的. ...
- HttpCanary——最强Android抓包工具!
迎使用HttpCanary——最强Android抓包工具! HttpCanary是一款功能强大的HTTP/HTTPS/HTTP2网络包抓取和分析工具,你可以把他看成是移动端的Fiddler或者Char ...
随机推荐
- tcp十种状态;关于tcp中time_wait状态(2MSL问题)
tcp十种状态 注意: 当一端收到一个FIN,内核让read返回0来通知应用层另一端已经终止了向本端的数据传送 发送FIN通常是应用层对socket进行关闭的结果 关于tcp中time_wait状态的 ...
- ORM-数据库命令操作包装实例对象学习
http://www.cnblogs.com/alex3714/articles/5978329.html python 之路,Day11 - sqlalchemy ORM 本节内容 ORM介绍 ...
- go实现pdf电子签名-自动识别签名位置
一. 技术选型 由于要识别签名位置,所以得要能解析pdf的文本布局,要能得到每个布局元素的文本位置坐标.而最终的签名需要合成到pdf上,所以还需要有编辑pdf的需求. pdf布局分析:pdfminer ...
- JAVA获取指定日期的周一的日期
/** * 获取当前周的周一的日期 * @param date 传入当前日期 * @return */ public static Date getThisWeekMonday(Date date) ...
- 【LeetCode】1111. Maximum Nesting Depth of Two Valid Parentheses Strings 有效括号的嵌套深度
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目讲解 划分规则讲解 返回结果讲解 解题方法 代码 日期 题目地址:ht ...
- 【九度OJ】题目1435:迷瘴 解题报告
[九度OJ]题目1435:迷瘴 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1435 题目描述: 通过悬崖的yifenfei,又面临 ...
- 【LeetCode】55. Jump Game 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 贪心 日期 题目地址:https://leetcod ...
- 【LeetCode】861. Score After Flipping Matrix 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】814. Binary Tree Pruning 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 日期 题目地址:https://leetc ...
- 1336 - Sigma Function
1336 - Sigma Function PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB S ...