From c35222b99c2244bc7beca7613dad98d95c8f71d7 Mon Sep 17 00:00:00 2001 From: xsx <825657193@qq.com> Date: Sun, 22 Oct 2023 21:19:03 +0800 Subject: [PATCH] =?UTF-8?q?websocket=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/PrivateMessageServiceImpl.java | 17 +-- im-ui/src/api/wssocket.js | 55 ++++---- im-ui/src/view/Home.vue | 22 ++- im-uniapp/App.vue | 28 +++- im-uniapp/common/request.js | 13 +- im-uniapp/common/wssocket.js | 129 ++++++++---------- im-uniapp/pages/chat/chat.vue | 5 + 7 files changed, 133 insertions(+), 136 deletions(-) diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java index 4dcbacc..269a937 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java @@ -62,25 +62,12 @@ public class PrivateMessageServiceImpl extends ServiceImpl sendMessage = new IMPrivateMessage<>(); - // 发送方的id和终端类型 - sendMessage.setSender(new IMUserInfo(1L, IMTerminalType.APP.code())); - // 对方的id - sendMessage.setRecvId(2L); - // 推送给对方所有终端 - sendMessage.setRecvTerminals(IMTerminalType.codes()); - // 同时推送给自己的其他类型终端 + sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal())); + sendMessage.setRecvId(msgInfo.getRecvId()); sendMessage.setSendToSelf(true); - // 需要回推发送结果,将在IMListener接收发送结果 - sendMessage.setSendResult(true); - // 推送的消息体 sendMessage.setData(msgInfo); - // 推送消息 imClient.sendPrivateMessage(sendMessage); - log.info("发送私聊消息,发送id:{},接收id:{},内容:{}", session.getUserId(), dto.getRecvId(), dto.getContent()); return msg.getId(); } diff --git a/im-ui/src/api/wssocket.js b/im-ui/src/api/wssocket.js index fbe4222..b54801f 100644 --- a/im-ui/src/api/wssocket.js +++ b/im-ui/src/api/wssocket.js @@ -2,29 +2,27 @@ var websock = null; let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码 let isConnect = false; //连接标识 避免重复连接 let wsurl = ""; -let userId = null; let accessToken = ""; let messageCallBack = null; let openCallBack = null; -let hasLogin = false; +let closeCallBack = null -let createWebSocket = (url, id,token) => { + +let init = (url,token) => { wsurl = url; - userId = id; accessToken = token; - initWebSocket(); }; -let initWebSocket = () => { +let connect = () => { try { - console.log("初始化WebSocket"); - closeWebSocket(); - hasLogin = false; + if (isConnect) { + return; + } + console.log("连接WebSocket"); websock = new WebSocket(wsurl); websock.onmessage = function(e) { let sendInfo = JSON.parse(e.data) - if (sendInfo.cmd == 0) { - hasLogin = true; + if (sendInfo.cmd == 0) { heartCheck.start() console.log('WebSocket登录成功') // 登录成功才算连接完成 @@ -32,15 +30,17 @@ let initWebSocket = () => { } else if (sendInfo.cmd == 1) { // 重新开启心跳定时 heartCheck.reset(); + console.log("") } else { // 其他消息转发出去 + console.log("收到消息:",sendInfo); messageCallBack && messageCallBack(sendInfo.cmd, sendInfo.data) } } websock.onclose = function(e) { console.log('WebSocket连接关闭') isConnect = false; //断开后修改标识 - reConnect(); + closeCallBack && closeCallBack(e); } websock.onopen = function() { console.log("WebSocket连接成功"); @@ -53,7 +53,6 @@ let initWebSocket = () => { } }; websock.send(JSON.stringify(loginInfo)); - } // 连接发生错误的回调方法 @@ -71,14 +70,17 @@ let initWebSocket = () => { //定义重连函数 let reConnect = () => { console.log("尝试重新连接"); - if (isConnect) return; //如果已经连上就不在重连了 + if (isConnect){ + //如果已经连上就不在重连了 + return; + } rec && clearTimeout(rec); rec = setTimeout(function() { // 延迟5秒重连 避免过多次过频繁请求重连 - initWebSocket(wsurl); + connect(); }, 5000); }; //设置关闭连接 -let closeWebSocket = () => { +let close = () => { websock && websock.close(); }; @@ -129,24 +131,25 @@ function sendMessage(agentData) { } -function onmessage(callback) { +function onMessage(callback) { messageCallBack = callback; } -function onopen(callback) { +function onOpen(callback) { openCallBack = callback; - if (hasLogin) { - openCallBack(); - } } - +function onClose(callback) { + closeCallBack = callback; +} // 将方法暴露出去 export { - createWebSocket, - closeWebSocket, + init, + connect, + close, sendMessage, - onmessage, - onopen + onOpen, + onMessage, + onClose } diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 1df0443..fabce88 100644 --- a/im-ui/src/view/Home.vue +++ b/im-ui/src/view/Home.vue @@ -83,11 +83,12 @@ this.$store.commit("setUserInfo", userInfo); this.$store.commit("setUserState", this.$enums.USER_STATE.FREE); this.$store.commit("initStore"); - this.$wsApi.createWebSocket(process.env.VUE_APP_WS_URL, userInfo.id, sessionStorage.getItem("accessToken")); - this.$wsApi.onopen(() => { + this.$wsApi.init(process.env.VUE_APP_WS_URL, sessionStorage.getItem("accessToken")); + this.$wsApi.connect(); + this.$wsApi.onOpen(() => { this.pullUnreadMessage(); }); - this.$wsApi.onmessage((cmd, msgInfo) => { + this.$wsApi.onMessage((cmd, msgInfo) => { if (cmd == 2) { // 异地登录,强制下线 this.$message.error("您已在其他地方登陆,将被强制下线"); @@ -106,6 +107,17 @@ this.handleGroupMessage(msgInfo); } }) + this.$wsApi.onClose((e) => { + console.log(e); + if(e.code == 1006){ + // 服务器主动断开 + this.$message.error("连接已断开,请重新登录"); + location.href = "/"; + }else{ + this.$wsApi.connect(); + } + }); + }, pullUnreadMessage() { // 拉取未读私聊消息 @@ -198,7 +210,7 @@ !msg.selfSend && this.playAudioTip(); }, handleExit() { - this.$wsApi.closeWebSocket(); + this.$wsApi.close(); sessionStorage.removeItem("accessToken"); location.href = "/"; }, @@ -246,7 +258,7 @@ }) }, unmounted() { - this.$wsApi.closeWebSocket(); + this.$wsApi.close(); } } diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue index 29800d8..83b0063 100644 --- a/im-uniapp/App.vue +++ b/im-uniapp/App.vue @@ -26,11 +26,13 @@ initWebSocket() { let loginInfo = uni.getStorageSync("loginInfo") let userId = store.state.userStore.userInfo.id; - wsApi.createWebSocket(process.env.WS_URL, loginInfo.accessToken); - wsApi.onopen(() => { + wsApi.init(process.env.WS_URL, loginInfo.accessToken); + wsApi.connect(); + wsApi.onOpen(()=>{ + // 拉取未读消息 this.pullUnreadMessage(); - }); - wsApi.onmessage((cmd, msgInfo) => { + }) + wsApi.onMessage((cmd, msgInfo) => { if (cmd == 2) { // 异地登录,强制下线 uni.showModal({ @@ -49,6 +51,19 @@ // 插入群聊消息 this.handleGroupMessage(msgInfo); } + }); + wsApi.onClose((res)=>{ + // 1006是服务器主动断开,3000是APP主动关闭 + if(res.code == 1006 || res.code == 3000){ + uni.showToast({ + title: '连接已断开,请重新登录', + icon: 'none', + }) + this.exit(); + }else{ + // 重新连接 + wsApi.connect(); + } }) }, pullUnreadMessage() { @@ -131,9 +146,9 @@ }, exit() { console.log("exit"); - wsApi.closeWebSocket(); + wsApi.close(); uni.removeStorageSync("loginInfo"); - uni.reLaunch({ + uni.navigateTo({ url: "/pages/login/login" }) }, @@ -198,4 +213,5 @@ // #endif background-color: #f8f8f8; } + \ No newline at end of file diff --git a/im-uniapp/common/request.js b/im-uniapp/common/request.js index f0ca4d7..42c8ff8 100644 --- a/im-uniapp/common/request.js +++ b/im-uniapp/common/request.js @@ -19,7 +19,7 @@ const request = (options) => { if (res.data.code == 200) { return resolve(res.data.data) } else if (res.data.code == 400) { - navToLogin(); + getApp().exit(); } else if (res.data.code == 401) { console.log("token失效,尝试重新获取") if (isRefreshToken) { @@ -36,7 +36,7 @@ const request = (options) => { requestList = []; isRefreshToken = false; console.log("刷新token失败") - navToLogin(); + getApp().exit(); return; } uni.setStorageSync("loginInfo", res.data.data); @@ -88,13 +88,4 @@ const reqRefreshToken = (loginInfo) => { }); } - -const navToLogin = () => { - uni.showToast({ - icon: "none", - title: "登录过期,请需要重新登录", - duration: 1500 - }) - getApp().exit(); -} export default request; \ No newline at end of file diff --git a/im-uniapp/common/wssocket.js b/im-uniapp/common/wssocket.js index 22e6fda..a724820 100644 --- a/im-uniapp/common/wssocket.js +++ b/im-uniapp/common/wssocket.js @@ -1,38 +1,20 @@ let wsurl = ""; let accessToken = ""; -let messageCallBack = null; let openCallBack = null; +let messageCallBack = null; +let closeCallBack = null; let isConnect = false; //连接标识 避免重复连接 -let hasLogin = false; let hasInit = false; -let createWebSocket = (url, token) => { + +let init = (url, token) => { wsurl = url; accessToken = token; - closeWebSocket().then(() => { - initWebSocket(); - }); - -}; - -let initWebSocket = () => { - console.log("初始化WebSocket"); - uni.connectSocket({ - url: wsurl, - success: (res) => { - console.log("websocket连接成功"); - }, - fail: (err) => { - console.log(e); - console.log("websocket连接失败"); - reConnect(); //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接 - } - }); - - // 不能绑定多次事件,不然多触发,即便之前已经调了uni.closeSocket + // 防止重新注册事件 if(hasInit){ return; } hasInit = true; + uni.onSocketOpen((res) => { console.log("WebSocket连接已打开"); isConnect = true; @@ -47,12 +29,10 @@ let initWebSocket = () => { data: JSON.stringify(loginInfo) }); }) - - + uni.onSocketMessage((res) => { let sendInfo = JSON.parse(res.data) if (sendInfo.cmd == 0) { - hasLogin = true; heartCheck.start() console.log('WebSocket登录成功') // 登录成功才算连接完成 @@ -66,58 +46,59 @@ let initWebSocket = () => { messageCallBack && messageCallBack(sendInfo.cmd, sendInfo.data) } }) - + uni.onSocketClose((res) => { console.log(res) console.log('WebSocket连接关闭') isConnect = false; //断开后修改标识 - //reConnect(); + closeCallBack && closeCallBack(res); }) - - uni.onSocketError((err) => { - console.log(err) + + uni.onSocketError((e) => { + console.log(e) isConnect = false; //连接断开修改标识 uni.showModal({ content: '连接失败,可能是websocket服务不可用,请稍后再试', showCancel: false, }) }) - }; -//定义重连函数 -let reConnect = () => { - console.log("尝试重新连接"); - if (isConnect) return; //如果已经连上就不在重连了 - rec && clearTimeout(rec); - rec = setTimeout(function() { // 延迟5秒重连 避免过多次过频繁请求重连 - initWebSocket(); - }, 5000); -}; - -//设置关闭连接 -let closeWebSocket = () => { - return new Promise((resolve, reject) => { - if (!isConnect) { - resolve(); - return; +let connect = ()=>{ + if (isConnect) { + return; + } + uni.connectSocket({ + url: wsurl, + success: (res) => { + console.log("websocket连接成功"); + }, + fail: (e) => { + console.log(e); + console.log("websocket连接失败,10s后重连"); + setTimeout(()=>{ + connect(); + },10000) } - uni.closeSocket({ - code: 3000, - complete: (res) => { - console.log("关闭websocket连接"); - hasLogin = false; - isConnect = false; - resolve(); - }, - fail:(e)=>{ - console.log("关闭websocket连接失败",e); - } - }) - - }) + }); +} +//设置关闭连接 +let close = () => { + if (!isConnect) { + return; + } + uni.closeSocket({ + code: 3000, + complete: (res) => { + console.log("关闭websocket连接"); + isConnect = false; + }, + fail:(e)=>{ + console.log("关闭websocket连接失败",e); + } + }); }; @@ -157,24 +138,26 @@ function sendMessage(agentData) { } -function onmessage(callback) { +function onMessage(callback) { messageCallBack = callback; } - -function onopen(callback) { +function onOpen(callback) { openCallBack = callback; - if (hasLogin) { - openCallBack(); - } +} + +function onClose(callback) { + closeCallBack = callback; } // 将方法暴露出去 export { - createWebSocket, - closeWebSocket, + init, + connect, + close, sendMessage, - onmessage, - onopen + onMessage, + onOpen, + onClose } \ No newline at end of file diff --git a/im-uniapp/pages/chat/chat.vue b/im-uniapp/pages/chat/chat.vue index af7e4ad..14b3225 100644 --- a/im-uniapp/pages/chat/chat.vue +++ b/im-uniapp/pages/chat/chat.vue @@ -98,6 +98,11 @@ return count; } }, + watch:{ + unreadCount(newCount,oldCount){ + this.refreshUnreadBadge(); + } + }, onLoad() { this.refreshUnreadBadge(); }