http的限制
我们都知道:http是请求——返回式地与服务器进行半双工(Half-duplex)通信。
单工simplex:只允许单方向传输
半双工half-duplex:一个时间只允许单方向传输
全双工full-duplex:同时允许双向传播
当客户端有需要的数据时:
- 首先三次握手和服务器建立一个TCP连接
- 客户端向服务端发起请求
- 服务器接收到请求,返回请求的数据/进行相应的操作后返回操作的结果。
请思考这样的场景: 在瞬息万变的股市里,用户需要获取实时的股市信息,用http要怎么实现?
如果我们采用轮询的方式,即客户端和服务器之间持久连接,客户端每隔一段时间都要去问服务器:你的数据有没有更新呀?更新的话就发给我吧~
如果我们采用长轮询的方式,即客户端发送一个请求到服务端,问数据有没有更新,如果没有坐下来和服务端喝喝茶(不是)没有更新的话,就一直等待,直到有数据的更新返回给客户端。
让我们想想这两种方式都有什么问题?
- 首先共同的的问题就是:每次发送请求都会带上header,数据频繁的更新,我们频繁的发送请求,但是其实header的信息是大量重复的,很消耗流量。
- 对于轮询:如果数据毫米ms级的更新,我们怎么控制发请求的频率?要每毫秒都发送一次吗?这样的话很快就达到了服务器的最大连接数而导致连接关闭。
对于长轮询:如果数据毫米ms级的更新,服务器在传送给客户端一个数据包之后,必须要等下一个GET请求到来了才能继续传数据包给客户端,这样的延迟是用户不能接受的。
websocket基本了解
由此诞生了websocket,他是一个事件驱动的、全双工、数据轻量的应用层协议,同http一样:基于可靠的TCP、运作在应用层。
websocket的优势支持双向通信,实时性强
- 数据轻量,WebSockets一般不使用XMLHttpRequest,因此,每次我们需要从服务器上获得更多信息时,都不会发送头信息。减少了被发送到服务器的数据负载。
- 单一TCP连接,在一开始升级HTTP连接后,客户端和服务器在WebSocket连接的整个生命周期内都通过该TCP连接(持久连接)进行通信
缺点
- 当连接终止时,websocket不会自动恢复
-
websocket 生命周期
请看下图:
可以看出一个websocket的生命周期为 首先TCP三次握手建立一个持久的连接(图中没有体现)
- 客户端通过http向服务器发起一个握手的请求,通过HTTP header里的Upgrade,申请协议升级,將HTTP协议更改為WebSocket协议
- 服务器接收到请求之后会返回response,响应协议升级
- 成功建立连接,可以愉快的进行全双工的通信啦~
以下来自请求头是我在b站爬的
Upgrade: websocket Connection: Upgrade Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits Sec-WebSocket-Key:2L8u5Rrk5YN0wKvZM1Ii4g== Sec-WebSocket-Version:13
其中:
Upgrade和Connection将http协议更改为websocket协议
Sec-WebSocket-*系列中的Sec-WebSocket-Version表示了此次使用的websocket版本,一般都是13
以下响应头也是我在b站爬的
Connection:upgrade Sec-WebSocket-Accept:/3LmuSOurCAPdn7LO9JdRkeheEk= Upgrade:websocket
表示服务器已经成功接收到请求,websocket连接已经成功建立啦~
websocket使用场景
在一些需要实时获取数据的场景,比如股市、直播、实时聊天、共享文档、实时地图等场景里使用。
在实际应用上
在实时场景上,其他用户如何获得某用户更新的数据呢?
可以看出,用户更新的数据其实是先提交到websocket server上,然后再由websocket server通过广播的形势把一个用户提交的数据派发到其他客户端。