什么是Websocket?
websocket支持端对端通讯,建立TCP连接完成握手后,可以与服务端建立持久连接,服务端可以给客户端发送消息,客户端也可以给服务端发送消息。
为什么会有websocket?
http是请求-响应模式,请求在前,响应在后,这就导致了服务器无法主动发送消息给客户端。
websocket适用场景:消息通知,直播间讨论区,聊天室,协同编辑。
websocket缺点:兼容性(HTML5新增,不支持老浏览器);因为维持TCP连接需要耗费资源,所以不适用消息量少的场景,否则会造成资源浪费。
Websocket出现前的解决方案
短轮询:客户端每隔一段时间就向服务器发送请求,询问有没有新的数据。
特点:实现简单,只需要设置一个定时器;但是会频繁建立关闭连接,发送大量无意义请求,且实时性并不高
长轮询:客户端发起请求,服务端阻塞不会立即返回,等有新消息时再响应;响应之后客户端立即又发起一次请求,重复整个流程。
特点:服务端阻塞占用资源;客户端长时间收不到消息可能会超市,从而主动断开与服务端的连接
Websocket的连接过程
- 建立HTTP连接,3次握手
- 请求头:connection:upgrade; upgrade:websocket; sec-websocket-key:skhfkdashfkj;
- 如果成功,StatusCode为101(switching protocols),响应头中的connection:upgrade;upgrade:websocket;sec-websocket-accept:sdfjalskjfhgsa;
- 升级到websocket协议后再开始通讯。
Websocket API 使用
let ws = new WebSocket("wss:xxxxxx")
ws.onopen = function(){
console.log("连接到了服务器")
}
ws.onmessage = function(e){
console.log("接收到了服务器的消息,既可以是文本,也可以是二进制",e.data)
}
ws.onclose = function(){
console.log("关闭连接了")
}
ws.send("发送消息")
// ws.close() // 关闭连接
// ws.readyState // 连接状态:0-正在连接中 1-已连接 2-正在关闭中 3-已关闭
Socket-io解决原生API了什么问题
问题:连接双方都可以在任何时候发送任何类型的数据,另一方如何准确知道数据的含义?
在http中,是通过path解决该问题
socket-io的解决方案:不同的消息放到不同的事件里,客户端和服务端约定事件类型,通过事件触发和监听不同事件。
心跳机制和断线重连
心跳机制:客户端每隔一段时间向服务器发送一个特有的心跳消息,每次服务端收到消息只需将消息返回,此时若二者还保持连接,则客户端就会收到消息;如果没有收到消息,则说明连接断开。此时客户端需要主动重连,完成一个周期。
为什么会出现心跳机制?
想想几个业务场景:
服务端挂了,半小时后服务重启成功了,但websocket没有连接了
用户断网了,网络恢复了,webscoket在断网后断开了连接,但是在网络恢复后没有连接上来
断线重连机制:用户断线或者服务端掉线之后,每隔一段时间重新new 一个websoket实例。new的过程就是连接的过程。
断线重连注意事项
1、开启时机:客户端监听发生错误或者掉线
2、设置重连锁,防止发送多个重连请求
3、开启重连次数限制,超过限制次数就停止重连