Home > Blockchain >  Adding a function to a Vuex plugin?
Adding a function to a Vuex plugin?

Time:10-04

I'm a beginner in vue and created my first application. I use vuex and I have a plugin to manage a webSocket to the server. Everything works fine as long as I only dealt with messages sent from the server to the browser.

I now would like to add a function to send messages through the socket if connected, but I'm not able to access the exported function. I'm also a beginner in Javascript programming.

Here is the plugin code:


var store = null;
var ws = null;

function startWebsocket() {
    ws = new WebSocket(process.env.VUE_APP_WEBSOCKET_URL)
    ws.onmessage = function (event) {
        console.log("webSocket: on message: ", event.data);
        store.dispatch('remoteMessage', event.data);
    }
    ws.onopen = function (event) {
        console.log("webSocket: on open: ", event)
        store.dispatch('connectionOpened');
    }
    ws.onclose = function (event) {
        console.log("webSocket: on close: ", event)
        store.dispatch('connectionClosed');
        ws = null
        setTimeout(startWebsocket, 5000)
    }    
    ws.onerror = function (event) {
        console.log("webSocket: on error: ", event)
    }
}

export default function createWebSocketPlugin() {
    return store_param => {
        store = store_param;
        startWebsocket();
    };
}

I would like to add the following function to the plugin so that I can call it from a vuex action function.

export function sendWebSocketMsg(msg) {
    if (ws) {
        ws.sendMsg(msg)
    }
}

In the vuex index.js file I have this:

. . .
import webSocket from '../plugins/webSocket'
. . .
export default new Vuex.Store({
  . . .
  actions: {
    connectionOpened({ commit }) {
      commit('SET_CONNECTION', true);
    },
    connectionClosed({ commit }) {
      commit('SET_CONNECTION', false);
    },
    connectionError({ commit }, error) {
      commit('SET_ERROR', error);
    },
    remoteMessage({commit}, message) {
      commit('SET_MESSAGE', message);
    },
    pause() {
      sendWebSocketMsg('{"pause":true}')
    },
    play() {
      sendWebSocketMsg('{"pause":false}')
    }
  }
}

The webSocket works well and reconnects automatically.

The only thing that I'm missing is the ability to send a webSocket message.

How do I have to modify the webSocket plugin ?

CodePudding user response:

ws variable is local to the module it was defined, this requires to modify plugin module in order for a function to access ws, e.g.:

export function sendWebSocketMsg(msg) {
    if (ws) {
        ws.sendMsg(msg)
    }
}

export default function createWebSocketPlugin() {...}

Then named export can be imported in module where it's used:

import webSocket, {sendWebSocketMsg} from '../plugins/webSocket'

CodePudding user response:

I answer my question since I found the solution. It is partly given in the tutorial I followed.

I wasn't aware of it, but the plugin is a vuex plugin.

The solution is to subscribe to a vuex method. I added the empty method SEND_MESSAGE to the vuex mutations.

  mutations: {
    SET_ERROR(state, errStr) {
      state.error = errStr;
    },
    SET_CONNECTION(state, status) {
      state.connected = status;
    },
    SET_MESSAGE(state, message) {
      let msg = JSON.parse(message);
      . . .
    },
    SEND_MESSAGE() {
    },
  },

I also added the application specific actions:

    pause({commit}) {
      commit('SEND_MESSAGE', '{"pause":true}');
    },
    play({commit}) {
      commit('SEND_MESSAGE', '{"pause":false}');
    },

I call the store actions from my components like this:

  methods: {
    pause() {
      this.$store.dispatch("pause");
    },
    play() {
      this.$store.dispatch("play");
    }
  },

The only change left to do is in the plugin. I subscribe a method to call to the SEND_MESSAGE mutation. This is how it is done:

export default function createWebSocketPlugin() {
    return store_param => {
        store = store_param;
        startWebsocket();
        store.subscribe((mutation, state) => {
            if (state.connected && mutation.type === 'SEND_MESSAGE' && ws) {
                console.log("webSocket send " mutation.payload);
                ws.send(mutation.payload);
            }
        });          
    };
}

I added the store.subscribe instruction. We only perform the operation when the mutation is of the right type and the web socket is connected.

  • Related