Vue - общий доступ к данным веб-сокета на вкладках браузера - PullRequest
1 голос
/ 23 апреля 2019

У меня проблемы с отправкой данных 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}`);
    }
  }
},

Я делаю что-то в корне неправильно? Это стандартный шаблон для этого? Я предполагаю, что это может быть как-то связано с тем, как SOCKET_ONMESSAGE вызывается в vue-native-websockets, так как он не запускается другой вкладкой браузера при использовании мутаций vuex-shared-mutations.

1 Ответ

0 голосов
/ 24 апреля 2019

Я удалил 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...