近期在开发一个类似于小年糕的小程序,当用户在合成影集后会立马跳到个人中心的影集列表,但是立刻跳过去,服务端并没有马上制作完成,所以会有个“影集正在制作中”的提示,为了避免用户退出页面重新请求查看影集是否制作完成,决定前后端通信采用websocket通信的方式,当有影集制作完成时,服务端可实时向用户推送消息。
websocket在实现时需要注意以下几点:
1. 微信小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该连接,并重新创建一个 WebSocket 连接。
2. WebSocket 链接默认和最大超时时间都是 60s,超过了这个时间会自动断开,所以要设置一个心跳链接。
3. 页面在卸载时要关闭socket的链接。
以下是websocket连接及心跳的实现
// 域名地址(项目实地址)
const Host = 'wss://xxxx:0000';
// Socket连接成功
var socketOpen = false;
// Socket关闭
var socketClose = false;
// 消息队列
var socketMsgQueue = [];
// 判断心跳变量
var heart = null;
// 心跳失败次数
var heartBeatFailCount = 0;
// 终止心跳
var heartBeatTimeout = null;
// 终止重连
var connectSocketTimeout = null;
var webSocket = {
// 连接Socket
connectSocket:function(options) {
wx.showLoading({
title: '正在请求中',
mask: true,
});
socketOpen = false;
socketClose = false;
socketMsgQueue = [];
wx.connectSocket({
url:Host,
success:function(res) {
if (options) {
options.success && options.success(res);
}
},
fail:function(res) {
if (options) {
options.fail && options.fail(res);
}
}
})
},
// 发送消息
sendSocketMessage:function(options) {
if (socketOpen) {
wx.sendSocketMessage({
data: options.msg,
success: function(res) {
if (options) {
options.success && options.success(res);
}
},
fail: function(res) {
if (options) {
options.fail && options.fail(res);
}
}
})
} else {
socketMsgQueue.push(options.msg)
}
},
// 关闭Socket
closeSocket: function(options) {
if (connectSocketTimeout) {
clearTimeout(connectSocketTimeout);
connectSocketTimeout = null;
};
socketClose = true;
this.stopHeartBeat();
wx.closeSocket({
success: function(res) {
if (options) {
options.success && options.success(res);
}
},
fail: function(res) {
if (options) {
options.fail && options.fail(res);
}
}
})
},
// 收到消息
onSocketMessageCallback: function(msg) {},
// 开始心跳
startHeartBeat: function() {
heart = true;
this.heartBeat();
},
// 正在心跳
heartBeat: function() {
var that = this;
if (!heart) {
return;
};
that.sendSocketMessage({
msg: JSON.stringify({
// 与后端约定,传点消息,保持链接
"msg_type": "heart"
}),
success: function(res) {
if (heart) {
heartBeatTimeout = setTimeout(() => {
that.heartBeat();
}, 7000);
}
},
fail: function(res) {
if (heartBeatFailCount > 2) {
that.connectSocket();
};
if (heart) {
heartBeatTimeout = setTimeout(() => {
that.heartBeat();
}, 7000);
};
heartBeatFailCount++;
},
});
},
// 结束心跳
stopHeartBeat: function() {
heart = false;
if (heartBeatTimeout) {
clearTimeout(heartBeatTimeout);
heartBeatTimeout = null;
};
if (connectSocketTimeout) {
clearTimeout(connectSocketTimeout);
connectSocketTimeout = null;
}
}
};
// 监听WebSocket打开连接
wx.onSocketOpen(function(res) {
wx.hideLoading();
// 如果已经关闭socket
if (socketClose) {
webSocket.closeSocket();
} else {
socketOpen = true
for (var i = 0; i < socketMsgQueue.length; i++) {
webSocket.sendSocketMessage(socketMsgQueue[i])
};
socketMsgQueue = []
webSocket.startHeartBeat();
}
});
// 监听WebSocket错误
wx.onSocketError(function(res) {
console.log('WebSocket连接打开失败,请检查!', res);
});
// 监听WebSocket接受到服务器的消息
wx.onSocketMessage(function(res) {
webSocket.onSocketMessageCallback(res.data);
});
// 监听WebSocket关闭连接后马上重连
wx.onSocketClose(function(res) {
if (!socketClose) {
clearTimeout(connectSocketTimeout);
connectSocketTimeout = setTimeout(() => {
webSocket.connectSocket();
}, 3000);
}
});
module.exports = webSocket;
以下是页面中的使用,其中在onSocketMessageCallback里面会有消息回调。
const WebSocket = require('../../public/websocket.js');
Page({
// 页面加载
onLoad: function(options) {
// 创建连接
WebSocket.connectSocket();
// 设置接收消息回调
WebSocket.onSocketMessageCallback = this.onSocketMessageCallback;
},
// Socket收到的信息
onSocketMessageCallback: function(res) {
console.log(res);
},
// 页面销毁时关闭连接
onUnload: function(options) {
WebSocket.closeSocket();
},
})
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有