为什么有WebSocket
HTTP 1.0
:单工通信
HTTP 1.1
:半双工通信
HTTP 2.0
:全双工通信
在HTTP 2.0
还没出来的时候,HTTP还未能做到全双工通信,也就是在同一时刻,数据的流动,总是单向的。
如果客户端想要知道服务端的信息,需要发一个请求去询问服务端,服务端才能把信息响应给客户端。
因此,服务端的信息无法实时地推送给服务端,从而在一定时间内产生了信息的误差。
要想消除这种误差,可以通过短轮询
和长轮询
的方式。
短轮询
短轮询,指在短时间内,频繁地向服务端发送数据请求,从而达到一个数据更新的效果。
长轮询
长轮询,服务端在收到客户端的请求后,并不会立刻响应,而是等到一段时间后,看是否有数据需要返回给客户端,有点像TCP中的延迟确认机制。
长轮询和短轮询都是基于HTTP协议的,两者都有比较明显的缺陷
- 短轮询会产生很多的无效请求,频繁地发送请求自然会带来额外的资源消耗
- 长轮询服务端也会占用一定的资源消耗,而且这个等待的时长,如何设置也是问题,设置地太长,就会产生较大的延迟,用户体验不高;如果太小,又会退化为短轮询
有没有什么办法能够让服务端自己意识到,自己是一个成熟的服务端,应该自己把数据主动地推送过来呢?WebSocket就是在此背景下,孕育而出。
什么是WebSocket
WebScoket的出现,解决了当时HTTP无法全双工通信的问题。
WebSocket特点:
- 建立在TCP协议之上,是应用层协议
- 与HTTP协议具有良好的兼容性,握手是基于HTTP协议。默认端口也是80和443
- 数据格式比轻量,性能开销小
- 可以发送文本,也可以发送二进制数据
如何建立WebSocket连接
连接建立过程:
借助HTTP,完成一次握手,即可建立连接。
- Connection字段:设置为Upgrade,表示客户端希望连接升级
- Upgrade字段:设置为WebSokcet,表示升级为WebSocket协议
- Sec-WebSocket-Key:客户端发送的一个 base64 编码的密文,用于简单的认证秘钥。要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept应答,否则客户端会抛出错误,并关闭连接
- Sec-WebSocket-Version :表示支持的Websocket版本
注意:
这里说的一次握手,并不是TCP三次握手的那个握手
WebSocket是应用层协议,TCP是传输层协议
WebSocket是基于TCP的,所以他最后还是会走三层握手来建立连接
至于为什么说他是一次握手,是基于应用层层面上的,只需要发送一次HTTP请求,即可建立WebSocket连接
应用场景
对于有时效性需求的业务场景,WebSocket都可以大展身手。
- 游戏
- 聊天室
- 基于位置的应用
- 弹幕