全篇干货无废话
实现微信小程序全局websocket
含掉线重连,心跳保活等机制,可做参考示例
app.js
// websocket连接地址
let wsUrl = "ws://192.168.100.20:8080/websocket";
App({
"globalData": {
"userInfo": wx.getStorageSync('userInfo'),
// websocket
websocket: null, // 连接对象
connectStatus: null, // 连接状态
heartbeatInterval: null, // 心跳定时器
dropReconnectInterval: null, // 掉线重连定时器
messageCallback: function() {
}, // 接收到消息函数
},
// ------------------------------- websocket -------------------------------
/* 打开小程序 */
onShow() {
// TODO 自行校验业务逻辑,验证登录等
// ......
// 连接socket
this.connectSocket();
},
/* 关闭小程序 */
onHide() {
const websocket = this.globalData.websocket,
heartbeatInterval = this.globalData.heartbeatInterval,
dropReconnectInterval = this.globalData.dropReconnectInterval;
// 关闭全局定时器
if (heartbeatInterval) clearInterval(heartbeatInterval);
if (dropReconnectInterval) clearInterval(dropReconnectInterval);
// 关闭socket
if (websocket) websocket.close();
this.globalData.websocket = null;
this.globalData.connectStatus = "quit";
this.globalData.heartbeatInterval = null;
this.globalData.dropReconnectInterval = null;
},
/* 连接socket */
connectSocket() {
const that = this, userInfo = this.globalData.userInfo;
this.globalData.connectStatus = null;
const websocket = wx.connectSocket({
url: wsUrl, timeout: 20000, header: {
'authorization': userInfo.token} });
websocket.onOpen(() => {
that.globalData.connectStatus = "success";
// 保活心跳
wx.hideLoading(); that.connectHeatbeat(); });
websocket.onClose(() => {
if (that.globalData.connectStatus != "quit")
that.globalData.connectStatus = "close"; });
websocket.onError(() => {
if (that.globalData.connectStatus != "quit")
that.globalData.connectStatus = "error"; });
// 接收消息事件
websocket.onMessage((res) => that.globalData.messageCallback(res));
this.globalData.websocket = websocket;
// 掉线重连检测
this.dropReconnect();
},
/* websocket掉线重连 */
dropReconnect: function() {
const dropReconnectInterval = this.globalData.dropReconnectInterval;
if (dropReconnectInterval) clearInterval(dropReconnectInterval);
this.globalData.dropReconnectInterval = setInterval((that) => {
const connectStatus = that.globalData.connectStatus;
if (connectStatus == null || connectStatus == "success") return;
// 掉线重连
wx.showLoading({
title: '掉线重连中...' });
clearInterval(that.globalData.dropReconnectInterval);
that.connectSocket();
}, 1000, this);
},
/* websocket心跳 */
connectHeatbeat() {
const heartbeatInterval = this.globalData.heartbeatInterval;
if (heartbeatInterval) clearInterval(heartbeatInterval);
// 保活,每3秒ping一次
this.globalData.heartbeatInterval = setInterval((that) => {
if (that.globalData.connectStatus == "quit")
clearInterval(that.globalData.heartbeatInterval);
else if (that.globalData.connectStatus == "success")
that.globalData.websocket.send({
data: 'ping' });
}, 3000, this);
},
/* 发送websocket消息 */
sendWebsocket(msg) {
const websocket = this.globalData.websocket,
connectStatus = this.globalData.websocket;
if (!websocket || connectStatus != 'success') return false;
websocket.send({
data: msg }); return true;
},
// ------------------------------- websocket -------------------------------
})
调用方式
发消息
app.sendWebsocket('我是消息内容');
接收消息
app.globalData.messageCallback = (res) => {
console.log("接收到websocket消息", res.data);
// TODO 执行后续业务逻辑
// ......
}