不一样的websocket封装简洁版
什么是websocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
可以实现后台向前台通信
初始化websocket的条件
登录了 但是没有websocket
let ws = new WS()ws.create()
心跳机制
客户端每隔一段时间向服务端发送一个特有的心跳消息,每次服务端收到消息后只需将消息返回,此时,若二者还保持连接,则客户端会收到消息若没收到,则说明连接断开,此时客户端就要主动连接,完成一个周期
短线重连
若某时间段内客户端发送了消息,而服务端未返回,则认定为断线,这个时候会触发到websocket中的onclose事件,需要重新连接服务
心跳检测 重连核心代码
- 服务端每隔30s会向前台返回心跳检测的消息
- 而断开重连需要40s秒
- 若果一切正常 那么每隔30s就会清除timer定时器,也就不会走到前台主动关闭和重连的代码
- 但是如果超过了40s 服务端没有向前台发送心跳检测的消息 就会触发断开重连的逻辑
const token = sessionStorage.getItem("token")
class WS {constructor(config = {}) {this.url = config.url || "localhost"this.port = config.url || 4000this.protocol = config.protocol || 'ws'// 心跳检测this.time = config.time || 30 * 1000this.ws = null}create() {this.ws = new WebSocket(`${this.protocol}://${this.url}:${this.port}`)this.ws.onopen = this.onOpenthis.ws.onmessage = this.onMessagethis.ws.onclose = this.onClosethis.ws.onerror = this.onError}onOpen = () => {/* 规定好发的必须是对象 对象里包含两个字段 type datawebsocket 是基于tcp 第一次连接靠的http 但是 不能修改header*/this.ws.send(// 鉴权请求JSON.stringify({type: "auth",data: token}))}onMessage = (e) => {<!-- 接受消息 -->console.log(e.data)let { type, data } = JSON.parse(e.data)switch (type) {case "noAuth":console.log("没有权限")break;case "heartCheck":this.checkServer()this.ws.send(JSON.stringify({ type: "heartCheck" }))break;case "default":console.log("message")}}onClose = () => {<!-- 断开连接 -->this.ws.close()}onError = () => {<!-- 错误,在1s 后触发重连 -->setTimeout(() => {this.create()}, 1000)}checkServer = () => {// 40s还未收到心跳 重新创建websocketclearTimeout(this.timer) //进来就清楚了 timer定时器 30s后又清除了 而 timer要 40s才会执行 所以心跳正常是不会走的<!-- 当30s后心跳没有返回,就会触发下面的函数关闭连接走到报错 重连-->this.timer = setTimeout(() => {this.onClose()this.onError()}, this.time + 1000 * 10)//短线重连}
}
export default WS