sharedWorker实现网站中多页面共享一个websocket连接
之前用websocket连接时候,没开一个页面就断开了上一个页面的链接,找了一下方法

html页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Example</title>
<script type="text/javascript">

</script>
</head>
<body>
<h1>WebSocket Chat Example</h1>
<div id="status">Connecting...</div>
<div id="messages"></div>
<a href="#" onclick="sendMessage()">fa</a>
</body>
<script>

   if (!window.SharedWorker) {
        alert('您的浏览器不支持 SharedWorker,请使用 Chrome/Firefox/Edge');
    }

     let uuid = ''
      const worker = new SharedWorker('worker.js');
      
      // 必须调用 start() 启用通信
      worker.port.start();
      
      // 接收 WebSocket 消息
      worker.port.onmessage = (e) => {
          if(e.data.type == 'on' && e.data.data == 'ok'){
              document.getElementById('status').innerText = '登录成功.';
          }
         if(e.data.type == 'ping'){
              console.log('ping');
          }
        if(e.data.type == 'msg'){

            try {
                const data = JSON.parse(e.data.data);
                console.log(data)
                if(data.message == 'Login successful'){
                    document.getElementById('status').innerText = '登录成功.';
                }else{
                    displayNewMessage(data);
                }
    
            } catch (e) {
                console.error('解析消息失败:', e);
            }


          }
           if (e.data.type === 'connect') {
                uuid = e.data.uuid;
                alert('连接成功')
                return;
            }
            console.log('Received:', e.data);
            
        
      };
    
    
      // 发送消息到 WebSocket
      function sendMessage() {
        worker.port.postMessage('Hello from page!');
      }
      
      
    window.onbeforeunload = function(e) {
        console.log(worker);
        worker.port.postMessage({
                "type": 'close',
                "uuid": "oe"
            });
    };



    function displayNewMessage(data) {
        const messageContainer = document.getElementById('messages');
        const newMessageElement = document.createElement('div');
        newMessageElement.innerText = `New Message: ${data.message}`;
        messageContainer.appendChild(newMessageElement);
    }
    
</script>
</html>

worker.js

// 存储所有连接的端口
const ports = [];
let socket;

// 当页面连接时触发
self.onconnect = (e) => {
  const port = e.ports[0];
  ports.push(port);

  // 初始化 WebSocket(仅首次连接时)
  if (!socket) {

    initWebSocket();

    function initWebSocket() {
        // WebSocket URL, replace with your server's WebSocket endpoint
        const wsURL = 'ws://8.137.90.97:2121/ws'; // Replace with actual URL

        socket = new WebSocket(wsURL);

        // Connection opened
        socket.addEventListener('open', onOpen);

        // Listen for messages
        socket.addEventListener('message', onMessage);

        // Listen for errors
        socket.addEventListener('error', onError);

        // Connection closed
        socket.addEventListener('close', onClose);
    }

    function onOpen(event) {
        console.log('已连接到WebSocket服务器。');
        //document.getElementById('status').innerText = '已连接到WebSocket服务器。';
        // Send login message or token here
        const loginData = {
            user_code: 'user',
            key: 'user_key', // Replace with actual user data
            server_password: 'myServerPassword'  // Replace with actual user data or use a token instead
        };

        socket.send(JSON.stringify(loginData));
    }

    function onMessage(event) {
        console.log('来自服务器的消息 ', event.data);


        // 广播消息给所有页面
        ports.forEach(p => p.postMessage({"type":"msg","data":event.data}));

        // Parse the incoming message and handle it accordingly
        // try {
        //     const data = JSON.parse(event.data);
        //     console.log(data)
        //     if(data.message == 'Login successful'){
        //         document.getElementById('status').innerText = '登录成功.';
        //     }else{
        //         displayNewMessage(data);
        //     }

        // } catch (e) {
        //     console.error('解析消息失败:', e);
        // }


    }

    function onError(event) {
        //document.getElementById('status').innerText = '观察到WebSocket错误:' + event;
        console.error('观察到WebSocket错误:', event);
    }

    function onClose(event) {
        console.log('WebSocket连接已关闭。正在尝试重新连接。。。');
        //document.getElementById('status').innerText = 'WebSocket连接已关闭。正在尝试重新连接。。。';
        // Optionally, you can check the event.code to determine why the connection was closed
        
        // Attempt to reconnect after a delay
        setTimeout(initWebSocket, 5000); // Retry every 5 seconds
    }


  }else{
    //广播消息给所有页面登录了
    ports.forEach(p => p.postMessage({"type":"on","data":'ok'}));
  }

  // 接收来自页面的消息
  port.onmessage = (e) => {
      console.log("页面",e.data)
       if (e.data.type === 'close') {
            const index = ports.indexOf(port);
            ports.splice(index, 1);
            return;
        }
  };
  
    setInterval(() => {
      ports.forEach(p => p.postMessage({"type":"ping","data":'1'}));
    }, 30000); // 每30秒发送心跳

};

Chrome 调试:
访问chrome://inspect/#workers
找到你的 SharedWorker 实例
点击 "inspect" 打开开发者工具

资料来源:
https://blog.csdn.net/2302_79230324/article/details/146770804
https://juejin.cn/post/7173701460947894308#heading-5
https://www.ruanyifeng.com/blog/2018/07/web-worker.html
https://www.cnblogs.com/imgss/p/14634577.html
https://juejin.cn/post/7413705154754347058#heading-7