不一样的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 || 4000
this.protocol = config.protocol || 'ws'
// 心跳检测
this.time = config.time || 30 * 1000
this.ws = null
}
create() {
this.ws = new WebSocket(`${this.protocol}://${this.url}:${this.port}`)
this.ws.onopen = this.onOpen
this.ws.onmessage = this.onMessage
this.ws.onclose = this.onClose
this.ws.onerror = this.onError
}
onOpen = () => {
/*
规定好发的必须是对象 对象里包含两个字段 type data
websocket 是基于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还未收到心跳 重新创建websocket
clearTimeout(this.timer) //进来就清楚了 timer定时器 30s后又清除了 而 timer要 40s才会执行 所以心跳正常是不会走的
<!-- 当30s后心跳没有返回,就会触发下面的函数
关闭连接
走到报错 重连
-->
this.timer = setTimeout(() => {
this.onClose()
this.onError()
}, this.time + 1000 * 10)//短线重连
}
}
export default WS