Vue-在浏览器标签之间共享WebSocket数据

时间:2019-04-23 19:49:27

标签: vue.js vuex

我无法将Websocket数据发送到多个标签。我尝试使用以下程序包实现。

这是我的测试场景:

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

myWebsocketExample.js(显示相关代码的片段)

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(显示相关代码的片段)

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

myTest.vue(显示相关代码的片段)

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时,似乎没有被其他浏览器选项卡触发。

1 个答案:

答案 0 :(得分:0)

我删除了vuex-shared-mutations,并提出了一种解决方法。我希望有一个更好的方法来实现这一目标。如果是这样,请让我知道!

myStore.js(显示相关代码的片段)

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(显示相关代码的片段)

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事件