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