欢迎大家来掘金找我玩~传送门
前言
作为一名入门不久的前端,平时接触最多的就是http/https
协议了,而对websocket
却不甚了解,最近看了一波资料,顺便在此做以总结~~ 欢迎大家交流指正~
http的限制
我们都知道:http是请求——返回式
地与服务器进行半双工
(Half-duplex)通信。
单工simplex:只允许单方向传输
半双工half-duplex:一个时间只允许单方向传输
全双工full-duplex:同时允许双向传播
当客户端有需要的数据时:
- 首先三次握手和服务器建立一个TCP连接
- 客户端向服务端发起请求
- 服务器接收到请求,返回请求的数据/进行相应的操作后返回操作的结果。
请思考这样的场景:
在瞬息万变的股市里,用户需要获取实时的股市信息,用http要怎么实现?
如果我们采用轮询
的方式,即客户端和服务器之间持久连接,客户端每隔一段时间都要去问服务器:你的数据有没有更新呀?更新的话就发给我吧~
如果我们采用长轮询
的方式,即客户端发送一个请求到服务端,问数据有没有更新,如果没有坐下来和服务端喝喝茶(不是)没有更新的话,就一直等待,直到有数据的更新返回给客户端。
让我们想想这两种方式都有什么问题?
-
首先共同的的问题就是:每次发送请求都会带上
header
,数据频繁的更新,我们频繁的发送请求,但是其实header的信息是大量重复的,很消耗流量。 -
对于轮询:如果数据
毫米ms
级的更新,我们怎么控制发请求的频率?要每毫秒都发送一次吗?这样的话很快就达到了服务器的最大连接数而导致连接关闭。 -
对于长轮询:如果数据
毫米ms
级的更新,服务器在传送给客户端一个数据包之后,必须要等下一个GET请求到来了才能继续传数据包给客户端,这样的延迟是用户不能接受的。
websocket基本了解
由此诞生了websocket,他是一个事件驱动的、全双工、数据轻量的应用层协议,同http
一样:基于可靠的TCP
、运作在应用层。
websoket的优势
- 支持双向通信,实时性强
- 数据轻量,WebSockets一般不使用
XMLHttpRequest
,因此,每次我们需要从服务器上获得更多信息时,都不会发送头信息
。减少了被发送到服务器的数据负载。 - 单一
TCP
连接,在一开始升级HTTP连接后,客户端和服务器在WebSocket连接的整个生命周期内都通过该TCP连接(持久连接)进行通信
缺点
- 当连接终止时,websocket不会自动恢复
- 2011年之前浏览器版本不支持
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
通过广播的形势把一个用户提交的数据派发到其他客户端。
总结
简单做一下总结,本文从why
、what
、how
几个维度阐述了websocket
的一些基础入门知识。其实还有很多实战的东西没有讲,后续还会继续更新~