微信小程序WebSocket实践
发布时间:2020-12-14 19:17:50 所属栏目:资源 来源:网络整理
导读:微信基础库1.7.0之后的版本提供了新版的WebSocket API,考虑到兼容性问题,尝试整合新旧两种版本的API,进行简单的封装。 从以下几个角度对微信小程序中所提供的WebSocket API封装 API兼容性 重连机制 小程序WebSocket API 旧版WebSocket API的使用 创建 - w
微信基础库1.7.0之后的版本提供了新版的WebSocket API,考虑到兼容性问题,尝试整合新旧两种版本的API,进行简单的封装。 从以下几个角度对微信小程序中所提供的WebSocket API封装
小程序WebSocket API旧版WebSocket API的使用
let socketOpen = false
const socketMsgQueue = []
// 连接socket
wx.connectSocket({
url: 'test.php'
})
// 监听打开事件
wx.onSocketOpen(function(res) {
socketOpen = true
for (let i = 0; i < socketMsgQueue.length; i++){
sendSocketMessage(socketMsgQueue[i])
}
socketMsgQueue = []
})
// 发送消息
function sendSocketMessage(msg) {
if (socketOpen) {
wx.sendSocketMessage({
data:msg
})
} else {
socketMsgQueue.push(msg)
}
}
新版WebSocket API的使用支持1.7.0+,连接后会返回一个SocketTask对象,在该对象上监听该连接的各种事件与执行发送消息等操作。 并发数
模块封装简单封装封装一个兼容新旧socketAPI的模块,仅考虑存在单个socket连接的情况 创建与事件监听
统一创建与添加监听函数 init() {
let st = this.connect()
this.listen(st)
this.manualClose = false
}
创建连接 connect() {
let st = wx.connectSocket(this.config.server)
return st
}
添加事件监听函数 listen(st) {
if (st !== undefined) {
this.ws = st
this.ws.onOpen(() => this.openHandle())
this.ws.onError(() => this.errorHandle())
this.ws.onClose(() => this.closeHandle())
this.ws.onMessage(res => this.messageHandle(res))
} else {
wx.onSocketOpen(() => this.openHandle())
wx.onSocketError(() => this.errorHandle())
wx.onSocketClose(() => this.closeHandle())
wx.onSocketMessage(res => this.messageHandle(res))
}
}
重连机制预设标记位 retryLock = false; // 避免多次同时重连
socketOpen = false; // 连接状态
manualClose = false; // 主动断开标记
在连接关闭监听函数中执行重连 closeHandle() {
console.info('WebSocket closed')
this.socketOpen = false
this.retryLock = false
// 不论是error还是close都会触发close事件,统一在这里进行重连
// 初次连接失败不进行重连(失败不会进入到onOpen的监听事件中,那时未声明retryTimes变量)
this.retryTimes !== undefined && this.reconnect()
}
判断重连锁与是否主动断开进行重连 reconnect() {
if (this.retryLock) return
// 若manualClose为true,表明不是主动断开
if (!this.manualClose) {
// 开始重连
setTimeout(() => {
this.retry()
},this.retryInterval)
}
}
重连函数,包含重连次数的限制 retry() {
if (
this.socketOpen ||
(this.retryTimes > 0 && this.retryCount <= this.retryTimes)
) {
console.warn(`reconnect ending. reconnect ${this.retryTimes} times`)
this.socketOpen) {
this.config.closeCallback()
}
return
}
this.retryTimes += 1
console.warn(`[ ${this.retryTimes} ]th reconnect WebSocket...`)
this.init()
}
消息队列添加消息队列,当重连后自动发送缓存消息 openHandle() {
this.retryTimes = 0
false
this.messageQueue.map(e => this.send(e))
this.messageQueue = []
}
若发送时断开则先将消息缓存到消息队列中 send(value) {
let data = this.msgWrapper(value)
data = JSON.stringify(data)
this.socketOpen) {
this.messageQueue.push(data)
} else {
this.ws) {
this.ws.send({ data })
} else {
wx.sendSocketMessage({ data })
}
}
}
辅助函数添加一些包裹消息格式的工具函数 messageIndex = 0;
helper = {
isPlainObject: val =>
Object.prototype.toString.call(val) === '[object Object]',nextId: () => {
this.messageIndex += 1
return this.messageIndex
},id: () => Date.now() + '.' + this.helper.nextId()
};
msgWrapper(data) {
let msg = data
this.helper.isPlainObject(msg)) {
if (msg.type) {
return msg
} else {
this.msgWrapper({ type: 'message',msg,id: this.helper.id() })
}
} this.helper.id() })
}
}
完整代码export default class WXWebSocket {
messageQueue = []; // 消息队列
retryLock = false; // 避免多次同时重连
socketOpen = false;
manualClose = // 主动断开标记
constructor(config) {
this.config = config || {}
// 重连间隔
this.retryInterval =
this.config.retryInterval && this.config.retryInterval > 100
? this.config.retryInterval
: 3000
// 重连次数
this.retryCount = this.config.retryCount || 5
this.init()
}
init() {
let st = this.connect()
this.listen(st)
false
}
connect() {
let st = wx.connectSocket(this.config.server)
console.log('current socket: ',st)
return st
}
listen(st) {
// 添加监听事件
if (st !== undefined) {
// 若存在SocketTask,则要通过readyState判断状态
// CONNECTING: 0
// OPEN: 1
// CLOSING: 2
// CLOSE: 3
this.ws = st
this.ws.onOpen(() => this.openHandle())
this.ws.onError(() => this.errorHandle())
this.ws.onClose(() => this.closeHandle())
this.messageHandle(res))
} else {
wx.onSocketOpen(() => this.openHandle())
wx.onSocketError(() => this.errorHandle())
wx.onSocketClose(() => this.closeHandle())
wx.onSocketMessage(res => this.messageHandle(res))
}
}
close() {
true
this.ws.close()
} else {
wx.closeSocket()
}
}
send(value) {
console.log('send value: ',value)
let this.msgWrapper(value)
data)
this.socketOpen) {
// add new message to queue
data)
} this.ws) {
data })
} else {
wx.sendSocketMessage({ data })
}
}
}
openHandle() {
console.info('WebSocket connected')
0
false
this.send(e))
this.messageQueue = []
}
errorHandle() {
console.error('WebSocket error')
false
}
closeHandle() {
console.info('WebSocket closed')
false
false
// 不论是error还是close都会触发close事件,统一在这里进行重连
// 初次连接失败不进行重连(失败不会进入到onOpen的监听事件中,那时未声明retryTimes变量)
this.reconnect()
}
reconnect() {
return
true
// 若manualClose为true,表明不是主动断开
this.manualClose) {
// 开始重连
setTimeout(() => {
this.retry()
},51); font-weight: 700;">this.retryInterval)
}
}
retry() {
if (
this.socketOpen ||
(this.retryTimes)
) {
console.warn(`end reconnect. reconnect ${this.retryTimes} times`)
this.socketOpen) {
this.config.closeCallback()
}
return
}
1
console.warn(`[ ${this.retryTimes} ]th reconnect WebSocket...`)
this.init()
}
messageHandle(res) {
this.config.responseCallback(res)
}
msgWrapper(data) {
let msg = data
this.helper.isPlainObject(msg)) {
if (msg.type) {
return msg
} else {
this.helper.id() })
}
} this.helper.id() })
}
}
messageIndex = 0;
helper = {
isPlainObject: val =>
Object.prototype.toString.call(1
this.messageIndex
},51); font-weight: 700;">this.helper.nextId()
};
}
使用创建连接发送消息
|