diff --git a/JeecgUniapp-master/src/common/socket.ts b/JeecgUniapp-master/src/common/socket.ts index f1f6fd73..7e0ad775 100644 --- a/JeecgUniapp-master/src/common/socket.ts +++ b/JeecgUniapp-master/src/common/socket.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { randomString } from './uitls' +import md5 from 'md5' import { useUserStore } from '@/store/user' const baseUrl = import.meta.env.VITE_SERVER_BASEURL @@ -8,66 +8,81 @@ class socket { constructor() { this.socketUrl = baseUrl this.socketStart = false - this.socketType = '' + this.socketType = 'websocket' + this._heartbeatTimer = null this.monitorSocketError() this.monitorSocketClose() this.socketReceive() } + + //update-begin---author:xsl ---date:2026-07-20 for:【APP对接真实IM】系统 WebSocket 地址与 PC 一致----------- + /** 构建系统 WebSocket 地址:/websocket/{userId}_{md5(token)} */ + buildSystemWebSocketUrl() { + const userStore = useUserStore() + const userId = userStore.userInfo.userid + const token = userStore.userInfo.token || '' + if (!userId || !this.socketUrl) { + return '' + } + const wsClientId = md5(token) + const base = this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://').replace(/\/$/, '') + return `${base}/websocket/${userId}_${wsClientId}` + } + //update-end---author:xsl ---date:2026-07-20 for:【APP对接真实IM】系统 WebSocket 地址与 PC 一致----------- + init(socket_type, callback?) { const userStore = useUserStore() - if (baseUrl) { - if (this.socketStart) { - console.log('webSocket已经启动了') - } else { - this.socketType = socket_type - let url = - this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://') + - '/' + - socket_type + - '/' + - userStore.userInfo.userid + - '_app' - if (socket_type == 'eoaNewChatSocket') { - let randomMessageId = randomString(6) - url = - this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://') + - '/eoaNewChatSocket/' + - userStore.userInfo.userid + - '/' + - randomMessageId - } - console.log('启动this.socketUrl连接地址:', url) - // update-begin-author:taoyan date:20220422 for:v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278 - - let token = userStore.userInfo.token - uni.connectSocket({ - url: url, - method: 'GET', - protocols: [token], - }) - // update-end-author:taoyan date:20220422 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278 - uni.onSocketOpen((res) => { - this.socketStart = true - callback && callback() - console.log('WebSocket连接已打开!') - }) - /* setTimeout(() => { - this.getHeartbeat(); - }, 5000); */ - } - } else { + if (!baseUrl) { console.log('config/baseUrl socketUrl为空') + return } + if (this.socketStart) { + console.log('webSocket已经启动了') + callback && callback() + return + } + this.socketType = socket_type || 'websocket' + //update-begin---author:xsl ---date:2026-07-20 for:【APP对接真实IM】连接原生 /websocket----------- + let url = this.buildSystemWebSocketUrl() + if (this.socketType !== 'websocket') { + // 兼容旧路径(如历史业务仍传入自定义 type) + url = + this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://') + + '/' + + this.socketType + + '/' + + userStore.userInfo.userid + + '_app' + } + //update-end---author:xsl ---date:2026-07-20 for:【APP对接真实IM】连接原生 /websocket----------- + if (!url) { + console.log('WebSocket url 为空,跳过连接') + return + } + console.log('启动this.socketUrl连接地址:', url) + const token = userStore.userInfo.token + uni.connectSocket({ + url: url, + method: 'GET', + protocols: [token], + }) + uni.onSocketOpen((res) => { + this.socketStart = true + callback && callback() + console.log('WebSocket连接已打开!') + this.startHeartbeat() + }) } + // Socket给服务器发送消息 send(data, callback) { const userStore = useUserStore() - if (userStore.userInfo.userid) { + if (userStore.userInfo.userid && typeof data === 'object' && data !== null) { data.userUid = userStore.userInfo.userid } - console.log(data) + const payload = typeof data === 'string' ? data : JSON.stringify(data) uni.sendSocketMessage({ - data: JSON.stringify(data), + data: payload, success: () => { callback && callback(true) }, @@ -76,61 +91,76 @@ class socket { }, }) } + acceptMessage(msg) { console.log(msg) } + // Socket接收服务器发送过来的消息 socketReceive() { uni.onSocketMessage((res) => { - console.log('APP:--》收到服务器内容:') - let data = JSON.parse(res.data) - // console.log('收到服务器内容:', data); + //update-begin---author:xsl ---date:2026-07-20 for:【APP对接真实IM】忽略心跳并解析 JSON----------- + if (res.data === 'ping' || res.data === 'pong') { + return + } + let data + try { + data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data + } catch (e) { + console.log('WebSocket 非 JSON 消息:', res.data) + return + } + //update-end---author:xsl ---date:2026-07-20 for:【APP对接真实IM】忽略心跳并解析 JSON----------- this.acceptMessage && this.acceptMessage(data) }) } + // 关闭Socket closeSocket() { + this.stopHeartbeat() uni.closeSocket() this.socketStart = false } + // 监听Socket关闭 monitorSocketClose() { uni.onSocketClose((res) => { console.log('WebSocket 已关闭!') this.socketStart = false + this.stopHeartbeat() setTimeout(() => { this.init(this.socketType) }, 3000) }) } + // 监听Socket错误 monitorSocketError() { - uni.onSocketError(function (res) { + uni.onSocketError((res) => { this.socketStart = false console.log('WebSocket连接打开失败,请检查!') }) } - // 心跳 - getHeartbeat() { - const userStore = useUserStore() - this.send( - { - type: '心跳', - userUid: userStore.userInfo.userid, - }, - (val) => { - setTimeout(() => { - if (val) { - // this.getHeartbeat(); - } else { - if (!this.socketStart) { - // this.init(); - } - } - }, 10000) - }, - ) + + //update-begin---author:xsl ---date:2026-07-20 for:【APP对接真实IM】心跳 ping----------- + startHeartbeat() { + this.stopHeartbeat() + this._heartbeatTimer = setInterval(() => { + if (!this.socketStart) { + return + } + this.send('ping') + }, 55000) } + + stopHeartbeat() { + if (this._heartbeatTimer) { + clearInterval(this._heartbeatTimer) + this._heartbeatTimer = null + } + } + //update-end---author:xsl ---date:2026-07-20 for:【APP对接真实IM】心跳 ping----------- } + const mySocket = new socket() export default mySocket diff --git a/JeecgUniapp-master/src/pages-message/chat/chat.vue b/JeecgUniapp-master/src/pages-message/chat/chat.vue index e9812681..1327f7fa 100644 --- a/JeecgUniapp-master/src/pages-message/chat/chat.vue +++ b/JeecgUniapp-master/src/pages-message/chat/chat.vue @@ -4,9 +4,9 @@ style: { navigationBarTitleText: '聊天', navigationStyle: 'custom', - disableScroll: true, // 微信禁止页面滚动 + disableScroll: true, 'app-plus': { - bounce: 'none', // 禁用 iOS 弹性效果 + bounce: 'none', }, }, } @@ -23,14 +23,14 @@ > - + @@ -38,354 +38,230 @@