You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NuxtJS v2.14.12中使用Shared-Workers共享WebSocket连接?

在NuxtJS中用Shared Worker实现多标签页WebSocket共享连接

核心思路

Nuxt PWA模块基于Workbox,我们可以通过自定义Workbox配置注入Shared Worker,让同域下的所有标签页复用同一个WebSocket连接,避免重复建立连接造成资源浪费。

具体实现步骤

1. 创建Shared Worker文件

在项目static目录下新建shared-worker.js,实现WebSocket的共享管理逻辑:

let socket = null;
const connections = new Set();

// 处理页面连接
self.onconnect = (e) => {
  const port = e.ports[0];
  connections.add(port);

  port.onmessage = (msg) => {
    switch(msg.data.type) {
      case 'INIT':
        if (!socket) {
          // 初始化WebSocket连接
          socket = new WebSocket('ws://你的后端WebSocket地址');
          
          socket.onopen = () => broadcast({ type: 'CONNECTED' });
          socket.onmessage = (event) => broadcast({ type: 'MESSAGE', data: event.data });
          socket.onerror = (error) => broadcast({ type: 'ERROR', error: error.message });
          socket.onclose = () => {
            broadcast({ type: 'DISCONNECTED' });
            socket = null;
          };
        } else {
          port.postMessage({ type: 'CONNECTED' });
        }
        break;
      case 'SEND':
        if (socket?.readyState === WebSocket.OPEN) {
          socket.send(msg.data.content);
        }
        break;
      case 'DISCONNECT':
        connections.delete(port);
        // 无页面连接时主动关闭WebSocket
        if (connections.size === 0 && socket) socket.close();
        break;
    }
  };

  port.start();
};

// 广播消息到所有关联页面
function broadcast(message) {
  connections.forEach(port => {
    try {
      port.postMessage(message);
    } catch(e) {
      connections.delete(port);
    }
  });
}

2. 配置Nuxt PWA的Workbox

修改nuxt.config.js中的pwa配置,将Shared Worker注入到Workbox并配置缓存:

export default {
  pwa: {
    workbox: {
      // 导入Shared Worker脚本
      importScripts: [
        '/shared-worker.js'
      ],
      // 缓存Shared Worker文件
      runtimeCaching: [
        {
          urlPattern: '/shared-worker.js',
          handler: 'CacheFirst',
          options: {
            cacheName: 'shared-worker-cache'
          }
        }
      ]
    }
  }
}

3. 封装页面端WebSocket操作插件

在plugins/websocket.js中封装Shared Worker的调用逻辑,全局注入到Nuxt应用:

class SharedWebSocket {
  constructor() {
    this.worker = new SharedWorker('/shared-worker.js');
    this.port = this.worker.port;
    this.listeners = {};

    this.port.onmessage = (e) => {
      const { type, data, error } = e.data;
      this.listeners[type]?.forEach(callback => callback(data, error));
    };

    this.port.start();
    this.init();
  }

  init() {
    this.port.postMessage({ type: 'INIT' });
  }

  send(content) {
    this.port.postMessage({ type: 'SEND', content });
  }

  on(type, callback) {
    if (!this.listeners[type]) this.listeners[type] = [];
    this.listeners[type].push(callback);
  }

  off(type, callback) {
    if (this.listeners[type]) {
      this.listeners[type] = this.listeners[type].filter(cb => cb !== callback);
    }
  }

  disconnect() {
    this.port.postMessage({ type: 'DISCONNECT' });
    this.port.close();
  }
}

export default ({ app }, inject) => {
  inject('websocket', new SharedWebSocket());
};

接着在nuxt.config.js中注册插件:

export default {
  plugins: [
    '~/plugins/websocket.js'
  ]
}

4. 在组件中使用共享连接

<template>
  <div>
    <input v-model="inputMsg" placeholder="输入消息">
    <button @click="sendMsg">发送</button>
    <div class="msg-list">
      <div v-for="msg in messages" :key="msg.id">
        {{ msg.content }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      inputMsg: '',
      messages: [],
      msgId: 0
    };
  },
  mounted() {
    this.$websocket.on('CONNECTED', () => console.log('WebSocket已连接'));
    this.$websocket.on('MESSAGE', (data) => {
      this.messages.push({ id: this.msgId++, content: data });
    });
    this.$websocket.on('DISCONNECTED', () => console.log('WebSocket已断开'));
  },
  beforeDestroy() {
    this.$websocket.disconnect();
  },
  methods: {
    sendMsg() {
      if (this.inputMsg.trim()) {
        this.$websocket.send(this.inputMsg);
        this.inputMsg = '';
      }
    }
  }
};
</script>

注意事项

  • Shared Worker仅支持同域页面共享,跨域场景无法使用
  • 浏览器兼容性:现代主流浏览器均支持Shared Worker,需确认目标运行环境
  • 更新Shared Worker代码后,需修改文件名或添加版本号(如shared-worker.v2.js)触发缓存刷新

内容的提问来源于stack exchange,提问作者Bruno Cardoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:45:43