rkljw 1 dienu atpakaļ
vecāks
revīzija
4b4ca7f6f8
2 mainītis faili ar 159 papildinājumiem un 30 dzēšanām
  1. 141 25
      src/layout/components/Chat/ChatPanel.vue
  2. 18 5
      src/utils/websocketService.js

+ 141 - 25
src/layout/components/Chat/ChatPanel.vue

@@ -1479,7 +1479,11 @@
         }
       },
       showMessage(item){
-        console.log("showMessage走没走",item)
+        console.log("showMessage走没走",item,"$$$$$$$$$$")
+        if(item=='pong' || item=='ping'){
+          console.log("心跳消息")
+          return;
+        }
         this.notificationShowMessage(item);
         this.playVoice();
       },
@@ -1497,7 +1501,7 @@
             <div
               class="my-custom-message"
               style="display:flex;align-items:center;background:#fff !important;color:#000 !important;padding:8px 16px;border-radius:4px;cursor:pointer;border:none !important;box-shadow:none !important;">
-              <img src="http://img.bjzxtw.org.cn/master/image/webp/chatinfo.png" style="width:24px;height:24px;margin-right:10px;" alt="info"/>
+              <img src="https://img.bjzxtw.org.cn/master/image/webp/chatinfo.png" style="width:24px;height:24px;margin-right:10px;" alt="info"/>
               <span>收到新消息</span>
             </div>
           `,
@@ -1515,8 +1519,8 @@
         }, 50);
       },
       playVoice(){
-        //http://img.bjzxtw.org.cn/master/video/mp3/11302.mp3 播放这段音频
-        const audio = new Audio('http://img.bjzxtw.org.cn/master/video/mp3/xxxtx.mp3');
+        //https://img.bjzxtw.org.cn/master/video/mp3/11302.mp3 播放这段音频
+        const audio = new Audio('https://img.bjzxtw.org.cn/master/video/mp3/xxxtx.mp3');
         
         if (this.userInteracted) {
           audio.play().catch(e => console.error('Audio play failed:', e));
@@ -1527,16 +1531,16 @@
       },
       notificationShowMessage(item) {
         const iconList = {
-          2:'http://img.bjzxtw.org.cn/master/www/icon/zixun.png',
-          3:'http://img.bjzxtw.org.cn/master/www/icon/sahngpin.png',
-          4:'http://img.bjzxtw.org.cn/master/www/icon/keti.png',//课题
-          5:'http://img.bjzxtw.org.cn/master/www/icon/tongzhi.png',//通知
-          6:'http://img.bjzxtw.org.cn/master/www/icon/tousu.png',//投诉
-          7:'http://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',
-          8:'http://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',
-          9:'http://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',
-          10:'http://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',
-          11:'http://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',
+          2:'https://img.bjzxtw.org.cn/master/www/icon/zixun.png',//资讯
+          3:'https://img.bjzxtw.org.cn/master/www/icon/sahngpin.png',//商品
+          4:'https://img.bjzxtw.org.cn/master/www/icon/keti.png',//课题
+          5:'https://img.bjzxtw.org.cn/master/www/icon/tongzhi.png',//通知公告
+          6:'https://img.bjzxtw.org.cn/master/www/icon/tousu.png',//投诉
+          7:'https://img.bjzxtw.org.cn/master/www/icon/shukan.png',//书刊
+          8:'https://img.bjzxtw.org.cn/master/www/icon/qiye.png',//企业
+          9:'https://img.bjzxtw.org.cn/master/www/icon/xiangmu.png',//项目
+          10:'https://img.bjzxtw.org.cn/master/www/icon/zhaopin.png',//招聘
+          11:'https://img.bjzxtw.org.cn/master/www/icon/qiuzhi.png',//求职
         }
         if (!('Notification' in window)) {
           this.$notify({
@@ -1597,7 +1601,7 @@
           if (Notification.permission === 'granted') {
             console.log("===============:Notification.permission === 'granted'",item)
             const notification = new Notification(item.user_name, {
-              icon: 'http://img.bjzxtw.org.cn/master/www/icon/group.png',
+              icon: 'https://img.bjzxtw.org.cn/master/www/icon/group.png',
               body: item.content,
               requireInteraction: true, // 需要用户交互才能关闭
               renotify: true, // 每次新消息都提醒
@@ -1632,11 +1636,109 @@
         }, item);
 
       },
+      // 处理心跳消息
+      handleHeartbeat(heartbeatMessage) {
+        try {
+          // 根据心跳消息类型回复不同的响应
+          let heartbeatResponse;
+          
+          if (heartbeatMessage === 'ping') {
+            // 简单的心跳,回复 pong
+            heartbeatResponse = 'pong';
+          } else {
+            // 复杂的心跳消息,回复结构化响应
+            heartbeatResponse = {
+              type: 'heartbeat_response',
+              timestamp: Date.now(),
+              original_message: heartbeatMessage
+            };
+          }
+          
+          // 通过 WebSocket 发送心跳响应
+          if (wsService.getReadyState() === WebSocket.OPEN) {
+            wsService.send(heartbeatResponse);
+            // console.log("心跳响应已发送:", heartbeatResponse);
+          } else {
+            console.warn("WebSocket 连接已断开,无法发送心跳响应");
+          }
+        } catch (error) {
+          console.error("处理心跳消息失败:", error);
+        }
+      },
+      // 启动心跳检测机制
+      startHeartbeatDetection() {
+        // 每30秒发送一次心跳
+        this.heartbeatInterval = setInterval(() => {
+          this.sendHeartbeat();
+        }, 30000);
+        
+        // 每90秒检查一次连接状态
+        this.connectionCheckInterval = setInterval(() => {
+          this.checkConnectionHealth();
+        }, 90000);
+      },
+      
+      // 发送心跳消息
+      sendHeartbeat() {
+        try {
+          if (wsService.getReadyState() === WebSocket.OPEN) {
+            // 发送简单的心跳消息
+            const heartbeatMessage = 'ping';
+            wsService.send(heartbeatMessage);
+            console.log("心跳消息已发送:", heartbeatMessage);
+          } else {
+            console.warn("WebSocket 连接已断开,尝试重连");
+            this.reconnectWebSocket();
+          }
+        } catch (error) {
+          console.error("发送心跳消息失败:", error);
+        }
+      },
+      
+      // 检查连接健康状态
+      checkConnectionHealth() {
+        if (wsService.getReadyState() !== WebSocket.OPEN) {
+          console.warn("检测到 WebSocket 连接异常,尝试重连");
+          this.reconnectWebSocket();
+        }
+      },
+      
+      // 重连 WebSocket
+      reconnectWebSocket() {
+        try {
+          console.log("开始重连 WebSocket...");
+          wsService.reconnect();
+          
+          // 重连成功后重新添加消息监听器
+          setTimeout(() => {
+            if (wsService.getReadyState() === WebSocket.OPEN) {
+              wsService.addMessageListener(this.handleIncomingMessage);
+              console.log("WebSocket 重连成功");
+            } else {
+              console.error("WebSocket 重连失败");
+            }
+          }, 1000);
+        } catch (error) {
+          console.error("重连 WebSocket 失败:", error);
+        }
+      },
+      
+      // 清除心跳检测定时器
+      clearHeartbeatTimers() {
+        if (this.heartbeatInterval) {
+          clearInterval(this.heartbeatInterval);
+          this.heartbeatInterval = null;
+        }
+        if (this.connectionCheckInterval) {
+          clearInterval(this.connectionCheckInterval);
+          this.connectionCheckInterval = null;
+        }
+      },
       //1.会话列表 start---------------------------------------->
       //1.1获取会话列表
       getConversationList(){
         this.$store.dispatch('chat/getConversation',{}).then(res=> {
-          console.log(res)
+          // console.log(res)
           let data = res.data;
           for(let item of data){
             item.status = 0; //默认未选中
@@ -1795,7 +1897,7 @@
         //console.log(message)
         //发送消息
         let that = this;
-        if (this.ws && wsService.getReadyState === WebSocket.OPEN) {
+        if (wsService.getReadyState() === WebSocket.OPEN) {
           //打开左侧loading防止重复点击
           this.hallLeftLoading = true;
           wsService.send(JSON.stringify(message));
@@ -2416,7 +2518,7 @@
   
           console.log(message)
           //发送消息
-          if (this.ws && wsService.getReadyState === WebSocket.OPEN) {
+          if (wsService.getReadyState() === WebSocket.OPEN) {
             wsService.send(message);
           }
           //关闭分享弹出框
@@ -2575,6 +2677,13 @@
           console.log("websocket连接成功!")
           return;
         }
+        
+        // 处理心跳消息
+        if(event === 'ping' || event.type === 'heartbeat' || event.msg_type === 'heartbeat' || event.action === 'heartbeat') {
+          console.log("收到心跳消息,回复心跳确认");
+          this.handleHeartbeat(event);
+          return;
+        }
         const message = event;
         this.conversationList.forEach(item => {
           if(item.receiver_id==message.receiver_id){
@@ -2714,7 +2823,7 @@
           };
           // console.log("websocket发送消息:",wsService.getReadyState,WebSocket.OPEN)
           //发送消息
-          console.log("发送消息前的状态:",wsService.getReadyState() ,"==========" ,WebSocket.OPEN,message)
+          // console.log("发送消息前的状态:",wsService.getReadyState() ,"==========" ,WebSocket.OPEN,message)
           if (wsService.getReadyState() === WebSocket.OPEN) {
             wsService.send(message);
           }
@@ -2733,8 +2842,9 @@
             content:this.sendMessage.img.imgUrl,//用户发发送的消息
             msg_type:2,//消息类型 1:文本 2:图片 3:文件 4:好友卡片 5:系统消息;6:加群卡片
           };
-          if (this.ws && wsService.getReadyState === WebSocket.OPEN) {
-            this.ws.send(JSON.stringify(message));
+          // console.log("发送图片消息前的状态:",wsService.getReadyState(),WebSocket.OPEN)
+          if (wsService.getReadyState() === WebSocket.OPEN) {
+            wsService.send(JSON.stringify(message));
             //发送完毕清除选择的图片
             this.sendMessage.img.imgUrl='';
           }
@@ -2757,8 +2867,8 @@
             content:fileInfoString,//用户发发送的消息
             msg_type:3,//消息类型 1:文本 2:图片 3:文件 4:好友卡片 5:系统消息;6:加群卡片
           };
-          if (this.ws && wsService.getReadyState === WebSocket.OPEN) {
-            this.ws.send(JSON.stringify(message));
+          if (wsService.getReadyState() === WebSocket.OPEN) {
+            wsService.send(JSON.stringify(message));
             //发送完毕清除选择的文件
             this.sendMessage.file.fileUrl='';
           }
@@ -2822,8 +2932,8 @@
   
           console.log(message)
           //发送消息
-          if (this.ws && wsService.getReadyState === WebSocket.OPEN) {
-            this.ws.send(JSON.stringify(message));
+          if (wsService.getReadyState() === WebSocket.OPEN) {
+            wsService.send(JSON.stringify(message));
           }
           //关闭分享弹出框
           this.userCardWindowStatus = false;
@@ -3288,6 +3398,9 @@
       // //let websocketNewUrl = URL.WebsocketUrl +"?token=" + adminToken;
       // this.ws = new WebSocket(websocketNewUrl);
       wsService.addMessageListener(this.handleIncomingMessage);
+      
+      // 启动心跳检测机制
+      this.startHeartbeatDetection();
   
       //3.当连接中断时提供一个方法重新连接
       let that = this;
@@ -3346,6 +3459,9 @@
       }
       clearInterval(this.getFriendApplyListStatus);
       wsService.removeMessageListener(this.handleIncomingMessage);
+      
+      // 清除心跳检测定时器
+      this.clearHeartbeatTimers();
     },
     watch: {
       // 监听 user.avatar 的变化

+ 18 - 5
src/utils/websocketService.js

@@ -1,4 +1,4 @@
-// src/services/websocketService.js
+// src/services/websocketService.js #
 import baseUrl from '@/utils/baseUrl';
 class WebSocketService {
   constructor() {
@@ -13,7 +13,7 @@ class WebSocketService {
     }
     const baseUrls = baseUrl.WebsocketUrl; // 替换为你的 ws 地址
     const url = `${baseUrls}?token=${token}`;
-    console.log('#############websocket url:', url);
+    // console.log('#############websocket url:', url);
     this.ws = new window.WebSocket(url);
 
     this.ws.onopen = () => {
@@ -22,8 +22,19 @@ class WebSocketService {
     };
 
     this.ws.onmessage = (event) => {
-      const message = JSON.parse(event.data);
-      console.log('#############websocket message:', message);
+      // console.log('#############websocket event:', event);
+      let message;
+      
+      try {
+        // 尝试解析为 JSON
+        message = JSON.parse(event.data);
+        console.log('#############websocket message:', message);
+      } catch (error) {
+        // 如果不是 JSON 格式,直接使用原始字符串
+        message = event.data;
+      }
+      
+      // console.log('#############websocket message:', message);
       this.messageListeners.forEach(cb => {
         if (typeof cb === 'function') {
           cb(message);
@@ -39,7 +50,9 @@ class WebSocketService {
 
   send(data) {
     if (this.ws && this.isConnected) {
-      this.ws.send(JSON.stringify(data));
+      // 如果 data 是字符串,直接发送;否则转换为 JSON
+      const message = typeof data === 'string' ? data : JSON.stringify(data);
+      this.ws.send(message);
     }
   }