这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
服务器主动发消息给客户端(看起来像也行)
那么聪明的你脑袋里相比已经有个大概了,没错:要么傻乎乎的使用 HTTP 轮询,要么就换用 ws
那么你生的再聪明一点(得罪你咩!)就一定会知道,HTTP 轮询亦有优劣之分:
普通 HTTP 持续轮询
我不断请求服务器,无响应就不做任何显示,有响应再说,这样用户直观感受就是好像从服务器那边收到了信息。
但是这样首先是占用了带宽,还增大了下游服务器的负载
其次是为了不过分请求,会设置 HTTP 请求之间的间隔,这会造成较为明显的卡顿
长轮询
说实在话,一般扫码场景这个就绰绰有余了
简单来说,就是大幅增加原来的请求超时时间,原本可能 3s 无应答就重新发送,现在改成 30s,那么在这个过程中,服务器收到扫码就返回响应,未收到就阻塞至超时,然后客户端重新发送请求。
像这种发起一个请求,在较长时间内等待服务器响应的机制,就是所谓的长训轮机制。我们常用的消息队列RocketMQ中,消费者去取数据时,也用到了这种方式。
像这种,在用户不感知的情况下,服务器将数据推送给浏览器的技术,就是所谓的服务器推送 技术,它还有个毫不沾边的英文名,comet 技术,大家听过就好。
当然,这个过程明眼人都看出来了,像扫码这样一段时间内就一次操作的环节可以这么干,可要是大型游戏,大量数据会从服务器发往客户端,这下该怎么办呢
websocket
我们知道TCP连接的两端,同一时间里,双方都可以主动向对方发送数据。这就是所谓的全双工。
而现在使用最广泛的HTTP1.1,也是基于TCP协议的,同一时间里,客户端和服务器只能有一方主动发数据,这就是所谓的半双工。
也就是说,好好的全双工TCP,被HTTP用成了半双工。
为什么?
这是由于HTTP协议设计之初,考虑的是看看网页文本的场景,能做到客户端发起请求再由服务器响应,就够了,根本就没考虑网页游戏这种,客户端和服务器之间都要互相主动发大量数据的场景。
所以为了更好的支持这样的场景,我们需要另外一个基于TCP的新协议。
于是新的应用层协议websocket就被设计出来了。
大家别被这个名字给带偏了。虽然名字带了个socket,但其实socket和websocket之间,就跟雷峰和雷峰塔一样,二者接近毫无关系。
总结
- TCP协议本身是全双工的,但我们最常用的HTTP1.1,虽然是基于TCP的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的websocket协议。
- 在HTTP1.1里。只要客户端不问,服务端就不答。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送(comet)的效果。
- 对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用websocket协议。
- websocket和socket几乎没有任何关系,只是叫法相似。
- 正因为各个浏览器都支持HTTP协议,所以websocket会先利用HTTP协议加上一些特殊的header头进行握手升级操作,升级成功后就跟HTTP没有任何关系了,之后就用websocket的数据格式进行收发数据。