WebSocket断开重连机制 实现demo,非采用onclose事件方式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebSocket断开重连机制 实现demo,非采用onclose事件方式相关的知识,希望对你有一定的参考价值。
参考技术A WebSocket.onclose 事件监听器 ,不可控性和断网情况下不触发问题,无法很好实现断线重连功能。我们解决方案是,根据服务端一定时间,自动给客户端推送的心跳,心跳来判断是否断开,如果一定时间内没有收到服务器发送的心跳,则会触发重连。(很像医生抢救重症病人,看心跳图没有波动,启用心电复苏)
uniapp即时聊天 websocket封装(建立连接断线重连心跳机制主动关闭)
- 使用 SocketTask 的方式去管理 webSocket 链接,每一条链路的生命周期都更加可控
- 可实现主动建立连接、心跳防断线机制、断线主动重连、提供主动断开的方法
一、如何使用 (uniapp Vue3)
<template>
// ...
</template>
<script setup>
import WS from './websocket'
import onLoad, onUnload from '@dcloudio/uni-app'
// 进入聊天页面初始化
let ws = null
onLoad((options) =>
ws = new WS(
// 连接websocket所需参数
data: userId: options.userId ,
// 首次连接成功之后,断线重新连接后也会触发(防止断线期间对方发送消息未接收到)
onConnected: () =>
// toDo
// 一般用于请求历史消息列表 getHistoryList()
,
// 监听接收到服务器消息
onMessage: (data) =>
// toDo
// 一般用于将最新的一条消息展示在页面上
)
)
// 发送消息
function sendMsg()
uni.request(
url: '后端url',
data: ...,
success: () =>
// 发送成功后,上方onMessage会接收到最新消息
)
// 页面销毁,断开websocket
onUnload(() =>
// 主动关闭websocket
ws.close()
)
</script>
二、websocket类代码
// 心跳间隔、重连websocket间隔,5秒
const interval = 5000
// 重连最大次数
const maxReconnectMaxTime = 5
export default class WS
constructor(options)
// 配置
this.options = options
// WS实例
this.socketTask = null
// 连接中
// 是否是正常关闭
this.normalClose = false
// 重新连接次数
this.reconnectTime = 1
// 重新连接Timer
this.reconnectTimer = null
// 心跳Timer
this.heartTimer = null
// 发起连接
this.initWS()
// 关闭WS
this.close = () =>
this.normalClose = true
this.socketTask.close()
clearInterval(this.heartTimer)
initWS()
// this.options.data 连接websocket所需参数
const url = 'wss://后端url' + this.options.data.userId
this.socketTask = uni.connectSocket( url, success() )
// 监听WS
this.watchWS()
watchWS()
// 监听 WebSocket 连接打开事件
this.socketTask.onOpen(() =>
console('websocket连接成功!')
// 连接成功
this.options.onConnected()
// 重置连接次数
this.reconnectTime = 1
// 发送心跳
this.onHeartBeat()
// 监听消息
this.onMessage()
// 关闭Toast
uni.hideLoading()
)
// 监听websocket 错误
this.socketTask.onError((res) =>
this.socketTask.close()
this.onDisconnected(res)
)
// 监听 WebSocket 连接关闭事件
this.socketTask.onClose((res) =>
// 非正常关闭
if (!this.normalClose)
this.onDisconnected(res)
)
// 监听消息
onMessage()
// 监听websocket 收到消息
this.socketTask.onMessage((res) =>
//收到消息
if (res.data)
this.options.onMessage(JSON.parse(res.data))
else
console('未监听到消息:原因:', JSON.stringify(res))
)
// 断开连接
onDisconnected(res)
console('websocket断开连接,原因:', JSON.stringify(res))
// 关闭心跳
clearTimeout(this.heartTimer)
// 全局Toast提示,防止用户继续发送
uni.showLoading( title: '消息收取中…' )
// 尝试重新连接
this.onReconnect()
// 断线重连
onReconnect()
clearTimeout(this.reconnectTimer)
if (this.reconnectTime < maxReconnectMaxTime)
this.reconnectTimer = setTimeout(() =>
console.log(`第【$this.reconnectTime】次重新连接中……`)
this.initWS()
this.reconnectTime++
, interval)
else
uni.showModal(
title: '温馨提示',
content: '服务器开小差啦~请返回聊天列表重试',
showCancel: false,
confirmText: '我知道了',
success: () =>
uni.navigateBack()
)
/** @心跳 **/
onHeartBeat()
this.heartTimer = setInterval(() =>
this.socketTask.send(
data: `heart:$this.options.data.userId`,
success()
console.log('心跳发送成功!')
)
, interval)
以上是关于WebSocket断开重连机制 实现demo,非采用onclose事件方式的主要内容,如果未能解决你的问题,请参考以下文章
uniapp即时聊天 websocket封装(建立连接断线重连心跳机制主动关闭)