- 将HaveADrink依赖从1.0.8升级至1.0.12版本 - 集成邀请码功能,新增common/invite.js处理邀请链路 - 实现发送好友请求返回邀请码的新流程 - 添加删除动态功能,新增DeleteFeed接口 - 集成UniAppWebSocket适配器,重构WebSocket连接管理 - 优化好友请求支持关键词搜索功能 - 在FeedCard组件中添加删除按钮和分享按钮 - 更新SDK类型定义文件以匹配新接口规范
157 lines
5.2 KiB
JavaScript
157 lines
5.2 KiB
JavaScript
/* 碰盏日记 - UniAppWebSocket 适配器
|
||
* 将 uni-app 的 uni.connectSocket 适配为 HaveADrink SDK WebsocketInterface
|
||
* (标准 WebSocket 风格:constructor(host)、onopen/onmessage/onclose/onerror、send、close)
|
||
* 用法:在 SDK 初始化时传入 websocket: UniAppWebSocket
|
||
*/
|
||
|
||
export default class UniAppWebSocket {
|
||
/**
|
||
* @param {string} host - 完整 ws/wss 连接地址(SDK 已处理 https→wss 协议转换)
|
||
*/
|
||
constructor(host) {
|
||
this.url = host
|
||
// 可赋值的事件回调(SDK ChatWebSocketConn.connect() 中直接赋值)
|
||
this.onopen = null
|
||
this.onmessage = null
|
||
this.onclose = null
|
||
this.onerror = null
|
||
// 连接状态: connecting | open | closed
|
||
this.readyState = 0
|
||
this._sendQueue = []
|
||
this._closedByUser = false
|
||
|
||
this._connect()
|
||
}
|
||
|
||
_connect() {
|
||
// 微信小程序下直接用 wx.connectSocket:
|
||
// uni 的 API 运行时(uni.api.esm.js)会向 connectSocket 注入 success/fail/complete 回调,
|
||
// 而微信规则是“传入回调后不再返回 SocketTask”,导致 uni.connectSocket 永远拿不到 task。
|
||
// wx.connectSocket 不传回调时正常返回 SocketTask,避免降级到全局 socket API
|
||
// (全局 API 重连时会重复注册监听器,引发重连风暴)
|
||
console.log('[UniAppWebSocket] 发起连接:', this.url)
|
||
const rawConnect = (typeof wx !== 'undefined' && typeof wx.connectSocket === 'function')
|
||
? wx.connectSocket.bind(wx)
|
||
: uni.connectSocket
|
||
const task = rawConnect({ url: this.url })
|
||
|
||
// 部分平台 uni.connectSocket 无返回值,降级为全局 API 监听
|
||
if (task && typeof task.onOpen === 'function') {
|
||
this.socketTask = task
|
||
|
||
task.onOpen((res) => {
|
||
console.log('[UniAppWebSocket] 连接已打开(open)')
|
||
this.readyState = 1
|
||
this._flush()
|
||
if (typeof this.onopen === 'function') {
|
||
this.onopen({ type: 'open' })
|
||
}
|
||
})
|
||
|
||
task.onMessage((res) => {
|
||
if (typeof this.onmessage === 'function') {
|
||
// 与浏览器 MessageEvent 对齐:消息内容放在 event.data
|
||
this.onmessage({ type: 'message', data: res.data })
|
||
}
|
||
})
|
||
|
||
task.onClose((event) => {
|
||
// 诊断:打印关闭码/原因,用于判断是服务端拒连还是网络问题
|
||
// 常见 code:1006 异常断开、1000 正常关闭;reason 由服务端给出
|
||
console.warn('[UniAppWebSocket] 连接被关闭(close) code:', event && event.code,
|
||
'reason:', event && event.reason)
|
||
this.readyState = 3
|
||
if (!this._closedByUser && typeof this.onclose === 'function') {
|
||
this.onclose(Object.assign({ type: 'close' }, event || {}))
|
||
}
|
||
})
|
||
|
||
task.onError((err) => {
|
||
// 诊断:微信会在 errMsg 中给出具体原因(域名不在合法列表、TLS 失败等)
|
||
console.warn('[UniAppWebSocket] 连接错误(error):', err && (err.errMsg || err.message || JSON.stringify(err)))
|
||
if (typeof this.onerror === 'function') {
|
||
this.onerror(Object.assign({ type: 'error' }, err || {}))
|
||
}
|
||
})
|
||
} else {
|
||
console.warn('[UniAppWebSocket] 未获得 SocketTask,降级到全局 socket API')
|
||
// 兜底:旧版小程序全局 socket API
|
||
uni.onSocketOpen(() => {
|
||
this.readyState = 1
|
||
this._flush()
|
||
if (typeof this.onopen === 'function') {
|
||
this.onopen({ type: 'open' })
|
||
}
|
||
})
|
||
uni.onSocketMessage((res) => {
|
||
if (typeof this.onmessage === 'function') {
|
||
this.onmessage({ type: 'message', data: res.data })
|
||
}
|
||
})
|
||
uni.onSocketClose((event) => {
|
||
this.readyState = 3
|
||
if (!this._closedByUser && typeof this.onclose === 'function') {
|
||
this.onclose(Object.assign({ type: 'close' }, event || {}))
|
||
}
|
||
})
|
||
uni.onSocketError((err) => {
|
||
if (typeof this.onerror === 'function') {
|
||
this.onerror(Object.assign({ type: 'error' }, err || {}))
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 发送数据(与浏览器 WebSocket.send 签名一致)
|
||
* @param {string} data
|
||
*/
|
||
send(data) {
|
||
if (this.readyState !== 1) {
|
||
// 连接未就绪时暂存,连接建立后补发
|
||
this._sendQueue.push(data)
|
||
return
|
||
}
|
||
if (this.socketTask) {
|
||
this.socketTask.send({
|
||
data,
|
||
fail: (err) => {
|
||
console.warn('[UniAppWebSocket] 发送失败', err)
|
||
}
|
||
})
|
||
} else {
|
||
// 兜底:旧版小程序全局 socket API
|
||
uni.sendSocketMessage({
|
||
data,
|
||
fail: (err) => {
|
||
console.warn('[UniAppWebSocket] 发送失败', err)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/** 主动关闭连接(主动关闭不再触发 onclose,由 SDK 自行控制重连) */
|
||
close() {
|
||
this._closedByUser = true
|
||
this.readyState = 3
|
||
if (this.socketTask) {
|
||
this.socketTask.close({
|
||
complete: () => {}
|
||
})
|
||
this.socketTask = null
|
||
} else {
|
||
uni.closeSocket({
|
||
complete: () => {}
|
||
})
|
||
}
|
||
}
|
||
|
||
/** 连接建立后补发暂存消息 */
|
||
_flush() {
|
||
if (!this._sendQueue.length) return
|
||
const queue = [...this._sendQueue]
|
||
this._sendQueue = []
|
||
queue.forEach((data) => this.send(data))
|
||
}
|
||
}
|