HTTP的缺陷
现在的应用场景可能更多的是,前端发起一次HTTP请求,服务器后端返回一次HTTP响应。但是有这样的场景,是需要服务器主动给前端发送请求的。
最常见的场景是扫码登陆。
这里有两种解决方案,一种是微信的解决方案,前端代码每隔一两秒就发送一个HTTP请求给服务器,这样服务器就能返回响应消息了。想一想是不是登陆微信扫码有时候会感觉卡了一两秒才登录,这是因为电脑登陆二维码出现后,手机扫了它,然后电脑隔一两秒发送一个询问给服务器,问这个二维码被扫了没有。
但是这个缺点非常明显,会不停的发送请求,这占用了带宽;即使一两秒可能有的人还是觉得卡不满意。
另一种是百度网盘的解决方案,叫长轮询。我们知道一般HTTP请求发出后,会给服务器留一定时间做响应,假设这个时间设置的比较长,比如30s,那服务器只要在30s内受到了扫码请求都可以立即返回给客户端。假设超时还没有返回,那就立马发起下一次请求。这样可以减少http请求数量。
这两种方式本质上还是客户端主动获取数据,扫码可能还好,假设是游戏的话,数据量非常庞大,那就没法主动推送给客户端了吗?实际上是有的,那就是WebSocket
全双工与半双工
TCP连接的两端,同一时间里,双方都可以主动向对方发送数据。这就是所谓的全双工。
而现在使用最广泛的HTTP/1.1,也是基于TCP协议的,同一时间里,客户端和服务器只能有一方主动发数据,这就是所谓的半双工。
也就是说,好好的全双工 TCP,被 HTTP/1.1 用成了半双工。
这是由于 HTTP 协议设计之初,考虑的是看看网页文本的场景,能做到客户端发起请求再由服务器响应,就够了,根本就没考虑网页游戏这种,客户端和服务器之间都要互相主动发大量数据的场景。
所以,为了更好的支持这样的场景,我们需要另外一个基于TCP的新协议。
于是新的应用层协议WebSocket就被设计出来了。
大家别被这个名字给带偏了。虽然名字带了个socket,但其实 socket 和 WebSocket 之间,就跟雷峰和雷峰塔一样,二者接近毫无关系。
怎么建立WebSocket连接
还是得先tcp三次握手,然后用http先进行一次通信,这里假设客户端想建立WebSocket连接,就可以在请求头里带上一些特殊字段:
返回字段101是指协议切换
WebSocket的使用场景
WebSocket完美继承了 TCP 协议的全双工能力,并且还贴心的提供了解决粘包的方案。
它适用于需要服务器和客户端(浏览器)频繁交互的大部分场景,比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件。