Files
hejiu/common/uni-websocket.js
T
cg 57eef74eb1 feat(sdk): 升级HaveADrink SDK并集成邀请系统
- 将HaveADrink依赖从1.0.8升级至1.0.12版本
- 集成邀请码功能,新增common/invite.js处理邀请链路
- 实现发送好友请求返回邀请码的新流程
- 添加删除动态功能,新增DeleteFeed接口
- 集成UniAppWebSocket适配器,重构WebSocket连接管理
- 优化好友请求支持关键词搜索功能
- 在FeedCard组件中添加删除按钮和分享按钮
- 更新SDK类型定义文件以匹配新接口规范
2026-08-04 23:32:45 +08:00

157 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 碰盏日记 - 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) => {
// 诊断:打印关闭码/原因,用于判断是服务端拒连还是网络问题
// 常见 code1006 异常断开、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))
}
}