赞
踩
近期在开发一个类似于小年糕的小程序,当用户在合成影集后会立马跳到个人中心的影集列表,但是立刻跳过去,服务端并没有马上制作完成,所以会有个“影集正在制作中”的提示,为了避免用户退出页面重新请求查看影集是否制作完成,决定前后端通信采用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 © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。