【问题标题】:Vue - Sharing websocket data across browser tabsVue - 跨浏览器选项卡共享 websocket 数据
【发布时间】:2019-09-13 01:32:09
【问题描述】:

我很难将 websocket 数据发送到多个选项卡。我尝试了使用以下包的实现。

这是我的测试场景:

  • 我打开了一个浏览器选项卡。然后我通过 websocket 发送数据。该选项卡会正确响应并查看传入的数据。
  • 当 websocket 仍在发送数据时,我现在打开了第二个浏览器选项卡。第一个选项卡仍然可以看到数据并正常运行。第二个选项卡看不到从 websocket 发送的数据。

myWebsocketExample.js(sn-p显示相关代码)

const express = require('express');
const app = express(); 

app.ws('test', (ws) => {
  ws.on('message', (msg) => {
    ws.send(new Date().toString());
  });
});
app.listen(9000);

myStore.js(sn-p显示相关代码)

import sharedMutations from 'vuex-shared-mutations';
mutations: {
    SOCKET_ONMESSAGE(state, message) {
      console.log(`Received ${message}`);
    },
},
plugins: [sharedMutations({ predicate: ['SOCKET_ONMESSAGE'] })],

myTest.vue(sn-p显示相关代码)

created() {
  this.$store.subscribe((mutation) => {
    if (mutation.type === 'myStore/SOCKET_ONMESSAGE') {
      console.log(`Received via subscription ${mutation.payload}`);
    }
  }
},

我做错了什么吗?这是这样做的标准模式吗?我猜这可能与在 vue-native-websockets 中调用 SOCKET_ONMESSAGE 的方式有关,因为在使用 vuex-shared-mutations 时,其他浏览器选项卡似乎不会触发它。

【问题讨论】:

    标签: vue.js vuex


    【解决方案1】:

    我删除了 vuex-shared-mutations 并想出了一个解决方法。我希望有更好的方法来实现这一目标。如果有,请告诉我!

    myStore.js(sn-p显示相关代码)

    import store from '@/store';
    
    function addDataToStore(state, message) {
      // Contains logic to add whatever data you have to the store
    }
    const channel = new BroadcastChannel('browser-tabs-test');
    channel.onmessage = (event) => {
      if (event.data.type === 'myCopy') {
        console.log('This browser tab received a copy of the original data);
        // Call a mutation so a class that is subscribed (aka this.$store.subscribe) 
        // will be alerted that this store instance has been updated with this data
        store.commit('myStore/SOCKET_ONMESSAGE_COPY', event.data.message);
      }
    };
    mutations: {
        SOCKET_ONMESSAGE(state, message) {
          console.log(`Received ${message}`);
          channel.postMessage({ type: 'myCopy', message });
          addDataToStore(state, message);
        },
        // Having a similar but separate mutation avoids infinite loops that 
        // would occur with the broadcast channel posting messages
        SOCKET_ONMESSAGE_COPY(state, message) {          
          console.log(`Received Copy of ${message}`);
          addDataToStore(state, message);
        },
    },
    

    myTest.vue(sn-p显示相关代码)

    created() {
      this.$store.subscribe((mutation) => {
        if (mutation.type === 'myStore/SOCKET_ONMESSAGE' ||
            mutation.type === 'myStore/SOCKET_ONMESSAGE_COPY'
        ) {
          console.log(`Received via subscription ${mutation.payload} from ${mutation.type}`);
          // Do something with the payload in this instance of the class
        }
      }
    },
    

    使用此代码时:

    • 浏览器标签 #1 仅接收 SOCKET_ONMESSAGE 事件和
    • 浏览器标签 #2 仅接收 SOCKET_ONMESSAGE_COPY 事件

    【讨论】: