websocket相较于HTTP的优势分析

  • 使用HTTP不断的轮询

    • 痛点在于,怎么样才能在用户不做任何操作的情况下,网页能收到消息并发生变更。

    • 常用的解决方案是,网页的前端代码里不断定时发 HTTP 请求到服务器,服务器收到请求后给客户端响应消息。「伪」服务器推的形式。

      • 场景也有很多,最常见的就是扫码登录。

        • 某信公众号平台,登录页面二维码出现之后,前端网页根本不知道用户扫没扫,于是不断去向后端服务器询问,看有没有人扫过这个码。而且是以大概 1 到 2 秒的间隔去不断发出请求,这样可以保证用户在扫码后能在 1 到 2 秒内得到及时的反馈,不至于等太久。

    • 用HTTP定时轮询两个比较明显的问题:

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

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

  • 长轮询

    • HTTP 请求发出后,一般会给服务器留一定的时间做响应,比如 3 秒,规定时间内没返回,就认为是超时。

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

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

    • 在用户不感知的情况下,服务器将数据推送给浏览器的技术,就是所谓的服务器推送技术,它还有个毫不沾边的英文名,comet 技术

    • 两种方式本质上,其实还是客户端主动去取数据。

  • websocket是什么

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

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

    • 怎么建立websocket连接

      • 一般都是在浏览器上刷的,这时候用的是 HTTP 协议

      • 一会打开网页游戏,这时候就得切换成我们新介绍的 WebSocket 协议

      • 浏览器在 TCP 三次握手建立连接之后,都统一使用 HTTP 协议先进行一次通信。

        • 如果此时是普通的 HTTP 请求,那后续双方就还是老样子继续用普通 HTTP 协议进行交互。

        • 如果这时候是想建立 WebSocket 连接,就会在 HTTP 请求里带上一些特殊的header 头

          • header 头的意思是,浏览器想升级协议(Connection: Upgrade),并且想升级成 WebSocket 协议(Upgrade: WebSocket)。同时带上一段随机生成的 base64 码(Sec-WebSocket-Key),发给服务器。

          • 如果服务器正好支持升级成 WebSocket 协议。就会走 WebSocket 握手流程,同时根据客户端生成的 base64 码,用某个公开的算法变成另一段字符串,放在 HTTP 响应的 Sec-WebSocket-Accept 头里,同时带上101状态码,发回给浏览器。响应如下

          • 101 确实不常见,它其实是指协议切换。

          • 浏览器也用同样的公开算法将base64码转成另一段字符串,如果这段字符串跟服务器传回来的字符串一致,那验证通过。

          • 就这样经历了一来一回两次 HTTP 握手,WebSocket就建立完成了,后续双方就可以使用 webscoket 的数据格式进行通信了。

    • websocket抓包

      • 经历了三次TCP握手之后,利用 HTTP 协议升级为 WebSocket 协议。

      • WebSocket只有在建立连接时才用到了HTTP,升级完成之后就跟HTTP没有任何关系了。

    • websocket的消息格式

      • 数据包在WebSocket中被叫做帧

        • opcode字段:这个是用来标志这是个什么类型的数据帧

          • 等于 1 ,是指text类型(string)的数据包

          • 等于 2 ,是二进制数据类型([]byte)的数据包

          • 等于 8 ,是关闭连接的信号

        • payload字段:存放的是我们真正想要传输的数据的长度,单位是字节。

        • 什么情况下应该读 7 bit,什么情况下应该读7+16bit呢?

          • WebSocket会用最开始的7bit做标志位。不管接下来的数据有多大,都先读最先的7个bit,根据它的取值决定还要不要再读个 16bit 或 64bit。

          • 如果最开始的7bit的值是 0~125,那么它就表示了 payload 全部长度,只读最开始的7个bit就完事了。

          • 如果是126(0x7E)。那它表示payload的长度范围在 126~65535 之间,接下来还需要再读16bit。这16bit会包含payload的真实长度。

          • 如果是127(0x7F)。那它表示payload的长度范围=65536,接下来还需要再读64bit。这64bit会包含payload的长度。这能放2的64次方byte的数据,换算一下好多个TB,肯定够用了。

        • payload data字段:这里存放的就是真正要传输的数据,在知道了上面的payload长度后,就可以根据这个值去截取对应的数据。

        • WebSocket的数据格式也是数据头(内含payload长度) + payload data 的形式。

        • 因为 TCP 协议本身就是全双工,但直接使用纯裸TCP去传输数据,会有粘包的"问题"。为了解决这个问题,上层协议一般会用消息头+消息体的格式去重新包装要发的数据。

        • 而消息头里一般含有消息体的长度,通过这个长度可以去截取真正的消息体。

    • websocket使用的场景

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

      • 适用于需要服务器和客户端(浏览器)频繁交互的大部分场景

        • 比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值