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.