//webSocket.ts
class WebsocketUtil {
	// WebSocket 服务器的 URL
	url : string
	// 心跳发送的间隔时间(秒)
	time : number
	// WebSocket 任务对象
	socketTask : any
	// WebSocket 连接是否打开
	isOpen : boolean
	// 重连定时器
	reconnectTimeout : NodeJS.Timeout | null
	// 心跳定时器
	heartbeatInterval : NodeJS.Timeout | null
	// 存储外部注册的消息回调函数的数组
	messageCallbacks : Array<(data : string) => void>

	// 构造函数,初始化 WebSocket 连接
	constructor(url : string, time : number) {
		this.url = url
		this.time = time
		this.socketTask = null
		this.isOpen = false
		this.reconnectTimeout = null
		this.heartbeatInterval = null
		this.messageCallbacks = []

		// 初始化 WebSocket 连接
		this.initializeWebSocket()
	}

	// 初始化 WebSocket 连接
	initializeWebSocket() {
		this.socketTask = uni.connectSocket({
			url: this.url,
			success: () => {
				console.log('WebSocket连接成功')
				this.isOpen = true
				// 连接成功后启动心跳和消息监听
				nextTick(() => {
					this.startHeartbeat()
					this.listenForMessages()
				})
			},
			fail: (error) => {
				console.error('WebSocket连接失败', error)
				this.reconnect()
			}
		})

		// 注意:这里的 onClose 监听器应该放在 uni.connectSocket 调用之后
		this.socketTask.onClose((result : any) => {
			this.isOpen = false
		})

		this.socketTask.onError((result : any) => {
			console.log(result)
		})
	}

	// 启动心跳检测
	startHeartbeat() {
		if (this.heartbeatInterval) {
			clearInterval(this.heartbeatInterval)
		}
		this.heartbeatInterval = setInterval(() => {
			if (this.isOpen) {
				this.send('ping')
			}
		}, this.time * 1000)
	}

	// 发送消息
	send(data : string) {
		console.log(data)
		if (this.socketTask && this.isOpen) {
			this.socketTask.send({
				data: data,
				success: (res : any) => {
					console.log('消息发送成功', res)
				},
				fail: (error : any) => {
					console.error('消息发送失败', error)
					if (!this.isOpen) {
						this.reconnect()
					}
				}
			})
		}
	}

	// 监听 WebSocket 消息
	listenForMessages() {
		if (this.socketTask) {
			this.socketTask.onMessage((res : { data : any }) => {
				const { data } = res
				this.messageCallbacks.forEach((callback) => callback(data.toString())) // 假设 data 是字符串或可转换为字符串
			})
		} else {
			console.log('WebSocket 连接尚未建立,无法监听消息')
		}
	}

	// 重连 WebSocket
	reconnect() {
		if (this.reconnectTimeout) {
			clearTimeout(this.reconnectTimeout)
		}
		this.reconnectTimeout = setTimeout(() => {
			this.initializeWebSocket()
		}, 3000)
	}

	// 关闭 WebSocket 连接
	closeSocket() {
		if (this.socketTask) {
			uni.closeSocket({
				success: () => {
					console.log('WebSocket连接已关闭')
					this.isOpen = false
				},
				fail: (error) => {
					console.error('关闭WebSocket连接失败', error)
				}
			})
			this.socketTask = null
		}
	}

	// 外部注册消息回调函数
	onMessage(callback : (data : string) => void) {
		this.messageCallbacks.push(callback)
	}

	// 外部注销消息回调函数
	offMessage(callback : (data : string) => void) {
		this.messageCallbacks = this.messageCallbacks.filter((cb) => cb !== callback)
	}

	// 销毁 WebSocket 连接,清理资源
	destroy() {
		this.closeSocket()
		clearInterval(this.heartbeatInterval)
		clearTimeout(this.reconnectTimeout)
		this.messageCallbacks = []
	}
}

export default WebsocketUtil
//main.ts

import WebSocket from './api/webSocket/webSocket'

app.config.globalProperties.$webSocket = WebSocket
//页面调用
const webSocket : any = ref()
const instance = getCurrentInstance()
...

const connectWS = async () => {
	const webSocketUtil = instance.appContext.config.globalProperties.$webSocket
	const provider = await getProvider()
	webSocket.value = new webSocketUtil(`wss://gate-test.juewei.cn/jw-online-app/order?token=${useGlobalStore().token}&memberGroupNo=${groupOrdering.memberGroupNo}&channelCode=${provider == 'weixin' ? '11' : '21'}`,5)}


onMounted(async () => {
	connectWS()
})
onUnmounted(() => {
	webSocket.value.destroy()
})

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐