005、计算机网络02-HTTP

HTTP

一、HTTP常见面试题

1、基本概念

(1)HTTP是什么?

HTTP,中文名为超文本传输协议。是一个在计算机世界中专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。

(2)HTTP常见的状态码

005、计算机网络02-HTTP_第1张图片

 

2、GET和POST

(1)区别

GET:

GET是获取服务器上的指定资源,请求参数一般写在URL中。

URL只能支持ASCII,而且浏览器对URL长度有限制。

GET请求没有请求体。

POST:

POST是根据请求负荷对指定的资源做出处理,携带的请求数据一般写在请求体中。

请求体中数据格式可以任意,大小也没有限制。

POST请求也可以将请求参数写在URL中

(2)安全和幂等

  • 安全:请求方法不会破坏服务器上的资源。

  • 幂等:多次执行相同的请求,结果一样。

  • GET请求安全且幂等,POST请求既不安全也不幂等。

3、HTTP的缓存

对于重复性的HTTP请求,每次获取到的数据都一样时,可以通过缓存技术减少获取服务器的响应。

HTTP缓存技术分为两种,强制缓存和协商缓存。

(1)强制缓存

强制缓存是浏览器判断缓存是否过期,未过期则直接使用缓存。

(2)协商缓存

通过服务端告知浏览器是否可以用缓存的方式,为协商缓存。只有在未命中强制缓存时,才能发起带有协商缓存字段的请求。

4、HTTP/1.1

(1)优点

简单、灵活和易于扩展、应用广泛和跨平台

报文格式为header+bodyheader也是key-value类型;

各类请求方法、URL、状态码等组成要求运行自定义扩充

(2)缺点

无状态、明文传输、不安全

(3)性能

长链接、管道运输

客户端和服务端,只要任意一端没有明确提出断开连接,则保持TCP连接状态;

在同一个TCP连接中,客户端可以发送多个请求,不必等响应结果,但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。

5、HTTP和HTTPS

(1)区别

  • HTTP 的信息是明文传输,HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。

  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。

  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。

  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

(2)HTTPS解决的问题

  • 信息加密:采用混合加密的方式实现信息的机密性;

  • 校验机制:摘要算法来确保数据的完整性;

  • 身份证书:数字证书解决被冒充的风险。

混合加密:

利用对称加密和非对称加密结合的混合加密方式,保证信息的机密性。

摘要算法+数字签名:

  • 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;

  • 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

数字证书:

通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。

(3)HTTPS建立连接流程

客户端向服务器端索要并验证服务器的公钥,双方协商生产会话秘钥。这就是TLS握手阶段,涉及四次通信,常用RSA算法和ECDHE算法。

RSA:

ClinetHello:

客户端给服务端发起加密通信请求,请求中包含客户端支持的TLS版本、生成的随机数(client random)、支持的密码套件。

ServerHello:

服务端接收到客户端请求后,发送响应,包含确认TLS版本、生成的随机数(server random)、确认的密码套件、服务器的数字证书。

客户端回应:

客户端收到服务端的响应后,确认服务端的数字证书有效性,取出服务器的公钥,生成加密报文。再次向服务端发送信息,一个随机数(pre-master key)、加密通信算法改变通知(以后都用会话秘钥进行加密通信)、客户端握手结束通知。

有了三个随机数和双方协商的加密算法,客户端生成本次通信的会话秘钥。

服务端响应:

服务端接收到第三个随机数,通过协商的加密算法,生成本次通信的会话秘钥。再次发送响应,加密通信算法改变通知(之后的所有通信都进行加密)、服务端握手结束通知。

至此,整个TLS的握手结束。客户端和服务端进入了加密通信,使用HTTP协议,只不过用会话秘钥进行加密内容。

(4)HTTPS应用数据完整性

TLS在实现上分为握手协议记录协议,握手协议是上面提到的四次握手(协商加密算法和生成对称秘钥),记录协议负责保护应用程序数据完整性。

005、计算机网络02-HTTP_第2张图片

记录协议完成后,将最终的报文数据传输到TCP层进行传输。

(5)HTTPS一定安全可靠

HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全。

二、HTTP1.1

005、计算机网络02-HTTP_第3张图片

1、基本介绍

(1)优点

  • 简单:

    • HTTP基本的报文格式是header+body,头部信息是key-value

  • 灵活:

    • HTTP协议里的各类请求方法、URL、状态码、头字段等每个组成要求都可自定义和扩充

  • 跨平台

(2)缺点

  • 无状态:

    • 每次请求都是新的请求,需要验证信息。

    • 解决无状态的比较简单方式是cookie技术,在返回给浏览器的响应中记录cookie。浏览器就会存储该数据,以后该浏览器的每次请求都会携带该cookie,cookie相当于存储在浏览器的数据。

  • 不安全:

    • HTTP的通信使用明文,内容会被窃听。

(3)性能

  • 长连接:

    • HTTP1.0的每次请求都基于TCP的三次握手协议,增加了通信开销。

    • 为此,HTTP1.1提出了长连接的通信方式,只要任意一端没有明确提出断开连接,则保持TCP连接状态。

  • 管道网络运输:

    • 采用长连接方式,使管道(pipeline)网络传输成为了可能。

    • 在同一个TCP连接里,客户端可以发起多个请求,不必等第一个响应回来,可以发送第二个请求,减少整体的响应时间。

    • 但服务端必须按照接收请求的顺序发送对这些管道化请求的响应,如果服务端在处理第一个请求时响应时间过长,后续的请求的处理都会被阻塞住,称之为队头阻塞。

  • 总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。

2、如何优化

  • 尽量避免发送 HTTP 请求

  • 在需要发送 HTTP 请求时,考虑如何减少请求次数

  • 减少服务器的 HTTP 响应的数据大小

(1)减少重复HTTP请求

对于重复性的HTTP请求,每次请求获得到的数据一样时,就可以将数据缓存在本地,不必每次通过网络获取服务端的响应。

强制缓存和协商缓存。

(2)减少请求次数

减少重定向请求次数;

合并请求;

延迟发送请求;

(3)减小HTTP响应数据

无损压缩和有损压缩

前置知识

1、密钥对

针对非对称加密,密钥对=私钥+公钥

2、私钥、公钥

公钥一般用来加密,私钥用来签名。

公钥和私钥唯一对应,用某个公钥签名过得内容只能用对应的私钥才能解签验证;同样用某个私钥加密的内容只能用对应的公钥才能解密。

3、摘要

对要传输的数据进行hash计算

4、签名

使用私钥对需要传输的数据的摘要进行加密

5、签名认证

数据接收端利用自己的公钥对签名进行解密

三、HTTPS的RSA握手解析

1、RSA握手过程

(1)第一次握手

客户端发一个Client Hello,消息里面有客户端使用的TLS版本、支持的密码套件列表,以及生成的随机数(client random)。client random会被服务端留下,以后用作生成对称加密秘钥的材料之一。

(2)第二次握手

服务端收到客户端的Hello,会确认TLS版本号是否支持,从密码套件列表中选择一个密码套件,以及服务端生成的随机数(server random)。

客户端和服务端互相打招呼的过程,就互相确认了支持的TLS版本号和即将要使用的密码套件,并且各自生成一个随机数,将随机数传递给对方。

服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书。

(3)客户端验证证书

客户端拿到了服务端的数字证书,需要验证有效性。一个数字证书通常包含:

  • 公钥;

  • 持有者信息;

  • 证书认证机构(CA)的信息;

  • CA 对这份文件的数字签名及使用的算法;

  • 证书有效期;

  • 还有一些其他额外信息;

    数字证书的作用为认证公钥持有者的身份,防止第三方冒充。

(4)第三次握手

客户端验证成功服务端的身份后,产生新的随机数(pre-master),利用RSA公钥加密后传递给服务端。服务端用私钥解密后,此时client和server端都含有了三个随机数,client randomserver random

pre-master

根据这三个随机数,双方生成会话秘钥(master secret)是对称秘钥,用于后续的HTTP请求/响应。

客户端发送一个Change Cipher Spec,告诉服务端开始使用加密方式发送消息。

客户端再发一个encrypted handshake message(finisher),把之前所有发送的数据做个摘要,再用会话秘钥加密一下,让服务器做个验证。

Change Cipher Spec之前传输的 TLS 握手数据都是明文,之后都是对称密钥加密的密文。

(5)第四次握手

服务器也是同样的操作,发Change Cipher SpecEncrypted Handshake Message消息,如果双方都验证加密和解密没问题,那么握手正式完成。

最后,就用「会话密钥」加解密 HTTP 请求和响应了。

2、RSA算法的缺陷

使用 RSA 密钥协商算法的最大问题是不支持前向保密

因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。

为了解决这个问题,后面就出现了 ECDHE 密钥协商算法,我们现在大多数网站使用的正是 ECDHE 密钥协商算法。

四、ECDHE算法握手

1、四次握手

(1)第一次握手

客户端首先会发一个「Client Hello」消息,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,以及生成的随机数(Client Random)

(2)第二次握手

服务端收到客户端的「打招呼」,同样也要回礼,会返回「Server Hello」消息,消息面有服务器确认的 TLS 版本号,也给出了一个随机数(Server Random),然后从客户端的密码套件列表选择了一个合适的密码套件。

接着,服务端为了证明自己的身份,发送「Certificate」消息,会把证书也发给客户端。

因为服务端选择了 ECDHE 密钥协商算法,所以会在发送完证书后,发送「Server Key Exchange」消息。

至此,TLS 两次握手就已经完成了,目前客户端和服务端通过明文共享了这几个信息:Client Random、Server Random 、使用的椭圆曲线、椭圆曲线基点 G、服务端椭圆曲线的公钥,这几个信息很重要,是后续生成会话密钥的材料。

(3)第三次握手

客户端验证服务端的证书,生成一个随机数作为客户端椭圆曲线的私钥,再根据服务端前面给的信息,生成客户端的椭圆曲线公钥,用「Client Key Exchange」消息发给服务端。

最终的会话密钥,就是用「客户端随机数 + 服务端随机数 + x(ECDHE 算法算出的共享密钥) 」三个材料生成的

算好会话密钥后,客户端会发一个「Change Cipher Spec」消息,告诉服务端后续改用对称算法加密通信。

接着,客户端会发「Encrypted Handshake Message」消息,把之前发送的数据做一个摘要,再用对称密钥加密一下,让服务端做个验证,验证下本次生成的对称密钥是否可以正常使用。

(4)第四次握手

最后,服务端也会有一个同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。于是,就可以正常收发加密的 HTTP 请求和响应了。

2、总结

  • RSA 密钥协商算法「不支持」前向保密,ECDHE 密钥协商算法「支持」前向保密;

  • 使用了 RSA 密钥协商算法,TLS 完成四次握手后,才能进行应用数据传输,而对于 ECDHE 算法,客户端可以不用等服务端的最后一次 TLS 握手,就可以提前发出加密的 HTTP 数据,节省了一个消息的往返时间(这个是 RFC 文档规定的,具体原因文档没有说明,所以这点我也不太明白);

  • 使用 ECDHE, 在 TLS 第 2 次握手中,会出现服务器端发出的「Server Key Exchange」消息,而 RSA 握手过程没有该消息;

五、HTTPS如何优化

由裸数据传输的HTTP协议转成加密数据传输的HTTPS协议,提高安全性的同时也带来了性能消耗。HTTPS比HTTP协议多出了一个TLS协议握手过程,目的是为了通过非对称加密握手协商或者交换出对称加密秘钥。

1、分析性能损耗

产生性能消耗的两个环节:

  • TLS协议的握手过程

  • 握手后的对称加密报文传输

2、优化点

硬件:CPU优化

软件:软件升级和协议优化

协议:密钥交换算法优化和TLS升级

证书:证书传输和证书验证优化

会话复用

六、HTTP/2

1、兼容HTTP/1.1

  • HTTP/2 没有在 URI 里引入新的协议名,仍然用「http://」表示明文协议,用「https://」表示加密协议,于是只需要浏览器和服务器在背后自动升级协议,这样可以让用户意识不到协议的升级,很好的实现了协议的平滑升级。

  • 只在应用层做了改变,还是基于 TCP 协议传输,应用层方面为了保持功能上的兼容,HTTP/2 把 HTTP 分解成了「语义」和「语法」两个部分,「语义」层不做改动,与 HTTP/1.1 完全一致,比如请求方法、状态码、头字段等规则保留不变。

2、头部压缩

(1)HTTP1.1存在的问题

HTTP协议的报文是由header+body构成的,HTTP1.1对于body部分进行了压缩,带对于header并未做出优化。

(2)HPACK算法

HTTP2对header部分进行了优化,使用HPACK算法进行压缩头部,HPACK算法主要包含三个部分:

  • 静态字典;

  • 动态字典;

  • Huffman 编码(压缩算法);

客户端和服务器两端都会建立和维护「字典」,用长度较小的索引号表示重复的字符串,再用 Huffman 编码压缩数据,可达到 50%~90% 的高压缩率

静态表只包含了 61 种高频出现在头部的字符串,不在静态表范围内的头部字符串就要自行构建动态表,它的 Index 从 62 起步,会在编码解码的时候随时更新。

3、二进制帧

HTTP/2 厉害的地方在于将 HTTP/1 的文本格式改成二进制格式传输数据,极大提高了 HTTP 传输效率,而且二进制数据使用位运算能高效解析。

4、并发传输

而 HTTP/2通过 Stream ,多个 Stream 复用一条 TCP 连接,达到并发的效果,解决了 HTTP/1.1 队头阻塞的问题,提高了 HTTP 传输的吞吐量。

HTTP/2 通过 Stream 实现的并发,比 HTTP/1.1 通过 TCP 连接实现并发要牛逼的多,因为当 HTTP/2 实现 100 个并发 Stream 时,只需要建立一次 TCP 连接,而 HTTP/1.1 需要建立 100 个 TCP 连接,每个 TCP 连接都要经过TCP 握手、慢启动以及 TLS 握手过程,这些都是很耗时的。

HTTP/2 还可以对每个 Stream 设置不同优先级,帧头中的「标志位」可以设置优先级,比如客户端访问 HTML/CSS 和图片资源时,希望服务器先传递 HTML/CSS,再传图片,那么就可以通过设置 Stream 的优先级来实现,以此提高用户体验。

5、服务器主动推送资源

客户端发起的请求,必须使用的是奇数号 Stream,服务器主动的推送,使用的是偶数号 Stream。服务器在推送资源时,会通过 PUSH_PROMISE 帧传输 HTTP 头部,并通过帧中的 Promised Stream ID 字段告知客户端,接下来会在哪个偶数号 Stream 中发送包体。

在 Stream 1 中通知客户端 CSS 资源即将到来,然后在 Stream 2 中发送 CSS 资源,注意 Stream 1 和 2 是可以并发的。

6、小结

HTTP/2 协议其实还有很多内容,比如流控制、流状态、依赖关系等等。

这次主要介绍了关于 HTTP/2 是如何提升性能的几个方向,它相比 HTTP/1 大大提高了传输效率、吞吐能力。

第一点,对于常见的 HTTP 头部通过静态表和 Huffman 编码的方式,将体积压缩了近一半,而且针对后续的请求头部,还可以建立动态表,将体积压缩近 90%,大大提高了编码效率,同时节约了带宽资源。

不过,动态表并非可以无限增大, 因为动态表是会占用内存的,动态表越大,内存也越大,容易影响服务器总体的并发能力,因此服务器需要限制 HTTP/2 连接时长或者请求次数。

第二点,HTTP/2 实现了 Stream 并发,多个 Stream 只需复用 1 个 TCP 连接,节约了 TCP 和 TLS 握手时间,以及减少了 TCP 慢启动阶段对流量的影响。不同的 Stream ID 可以并发,即使乱序发送帧也没问题,比如发送 A 请求帧1-> B 请求帧1-> A 请求帧2 -> B 请求帧2,但是同一个 Stream 里的帧必须严格有序。

另外,可以根据资源的渲染顺序来设置 Stream 的优先级,从而提高用户体验。

第三点,服务器支持主动推送资源,大大提升了消息的传输性能,服务器推送资源时,会先发送 PUSH_PROMISE 帧,告诉客户端接下来在哪个 Stream 发送资源,然后用偶数号 Stream 发送资源给客户端。

HTTP/2 通过 Stream 的并发能力,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。

HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。

七、HTTP/3

1、HTTP2的缺陷

HTTP/2 通过头部压缩、二进制编码、多路复用、服务器推送等新特性大幅度提升了 HTTP/1.1 的性能,而美中不足的是 HTTP/2 协议是基于 TCP 实现的,于是存在的缺陷有三个。

  • 队头阻塞;

  • TCP 与 TLS 的握手时延迟;

  • 网络迁移需要重新连接;

(1)队头阻塞

005、计算机网络02-HTTP_第4张图片 

一个流中的数据丢失了,会影响到其他流的请求。

因为 TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且有序的,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看,就是请求被阻塞了。

(2)TCP和TLS的握手延迟

发起 HTTP 请求时,需要经过 TCP 三次握手和 TLS 四次握手(TLS 1.2)的过程,因此共需要 3 个 RTT 的时延才能发出请求数据。

另外, TCP 由于具有「拥塞控制」的特性,所以刚建立连接的 TCP 会有个「慢启动」的过程,它会对 TCP 连接产生"减速"效果。

(3)网络迁移需要重新连接

005、计算机网络02-HTTP_第5张图片

一个 TCP 连接是由四元组(源 IP 地址,源端口,目标 IP 地址,目标端口)确定的,这意味着如果 IP 地址或者端口变动了,就会导致需要 TCP 与 TLS 重新握手,这不利于移动设备切换网络的场景,比如 4G 网络环境切换成 WIFI。

2、QUIC协议的特点

UDP 是一个简单、不可靠的传输协议, UDP 包之间是无序的,没有依赖关系。

UDP 是不需要连接的,也就不需要握手和挥手的过程,所以天然的就比 TCP 快。

HTTP/3 不仅仅只是简单将传输协议替换成了 UDP,还基于 UDP 协议在「应用层」实现了 QUIC 协议,它具有类似 TCP 的连接管理、拥塞窗口、流量控制的网络特性,相当于将不可靠传输的 UDP 协议变成“可靠”的了,所以不用担心数据包丢失的问题。

QUIC 协议的优点有很多,这里举例几个,比如:

  • 无队头阻塞;

  • 更快的连接建立;

  • 连接迁移;

(1)无队头阻塞

005、计算机网络02-HTTP_第6张图片 

QUIC 连接上的多个 Stream 之间没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响。

(2)更快的连接建立

对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。

但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商,甚至在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果

(3)连接迁移

而 QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

3、总结

HTTP/2 虽然具有多个流并发传输的能力,但是传输层是 TCP 协议,于是存在以下缺陷:

  • 队头阻塞,HTTP/2 多个请求跑在一个 TCP 连接中,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看,就是多个请求被阻塞了;

  • TCP 和 TLS 握手时延,TCL 三次握手和 TLS 四次握手,共有 3-RTT 的时延;

  • 连接迁移需要重新连接,移动设备从 4G 网络环境切换到 WIFI 时,由于 TCP 是基于四元组来确认一条 TCP 连接的,那么网络环境变化后,就会导致 IP 地址或端口变化,于是 TCP 只能断开连接,然后再重新建立连接,切换网络环境的成本高;

HTTP/3 就将传输层从 TCP 替换成了 UDP,并在 UDP 协议上开发了 QUIC 协议,来保证数据的可靠传输。

QUIC 协议的特点:

  • 无队头阻塞,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,也不会有底层协议限制,某个流发生丢包了,只会影响该流,其他流不受影响;

  • 建立连接速度快,因为 QUIC 内部包含 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与 TLS 密钥协商,甚至在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果。

  • 连接迁移,QUIC 协议没有用四元组的方式来“绑定”连接,而是通过「连接 ID 」来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本;

另外 HTTP/3 的 QPACK 通过两个特殊的单向流来同步双方的动态表,解决了 HTTP/2 的 HPACK 队头阻塞问题。

八、WebSocket

既然有 HTTP 协议,为什么还要有 WebSocket?

看起来服务器主动发消息给客户端的场景,是怎么做到的?

1、HTTP不断轮询

在前端代码里不断定时发送HTTP请求到服务器,服务器接收到请求后给客户端响应,这是一种伪服务器推的形式。

但这样,会有两个比较明显的问题:

  • 当你打开 F12 页面时,你会发现满屏的 HTTP 请求。虽然很小,但这其实也消耗带宽,同时也会增加下游服务器的负担。

  • 最坏情况下,用户在扫码后,需要等个 1~2 秒,正好才触发下一次 HTTP 请求,然后才跳转页面,用户会感到明显的卡顿

使用起来的体验就是,二维码出现后,手机扫一扫,然后在手机上点个确认,这时候卡顿等个 1~2 秒,页面才跳转。

2、长轮询

每次HTTP请求几乎都会留给服务器一定的时间做响应,在这段时间内没有返回响应意味着超时。

如果将 HTTP 请求的超时设置的很大,比如 30 秒,在这 30 秒内只要服务器收到了扫码请求,就立马返回给客户端网页。如果超时,那就立马发起下一次请求。

像这种在较长时间内等待服务器响应的机制,就是所谓的长轮询机制。常用的消息队列RokcetMQ中,消费者去取数据时,也用到了这种方式。

3、WebSocket

TCP 连接的两端,同一时间里双方都可以主动向对方发送数据。这就是所谓的全双工

HTTP/1.1,也是基于TCP协议的,同一时间里,客户端和服务器只能有一方主动发数据,这就是所谓的半双工

客户端和服务器之间都要互相主动发大量数据的场景,新的应用层协议WebSocket就被设计出来了。

(1)怎么建立WebSocket连接

浏览器在TCP三次握手建立连接后,都统一使用HTTP协议先进行一次通信,如果想建立WebSocket连接,就会在HTTP请求头中带上一些特殊字段。

如果服务器正好支持升级成 WebSocket 协议,就会走 WebSocket 握手流程。

(2)使用场景

WebSocket完美继承了 TCP 协议的全双工能力,并且还贴心的提供了解决粘包的方案。

它适用于需要服务器和客户端(浏览器)频繁交互的大部分场景,比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件。

在使用 WebSocket 协议的网页游戏里,怪物移动以及攻击玩家的行为是服务器逻辑产生的,对玩家产生的伤害等数据,都需要由服务器主动发送给客户端,客户端获得数据后展示对应的效果。

你可能感兴趣的:(计算机网络,http,网络)