Open flip111 opened 6 years ago
Found this, but don't really understand it https://forum.vuejs.org/t/referencing-vue-instance-in-vuex/14678/9 in the end the guy doesn't seem to use the vue-native-websocket anymore though
import WebSocket from 'simple-websocket'
Vue.prototype.$ws = new WebSocket('URL')
Maybe this helps:
assign your function to the listener in the created
method of your Component:
created () {
this.$options.sockets.onmessage = (data) => this.messageReceived(data)
},
Thank you @anthu ! by the way .. since then i also found another method to get the value in a template
computed: {
socketMessage() {
return this.$store.state.message
},
},
<template>
<div>{{socketMessage}}</div>
</template>
Perhaps both methods can be added to the readme?
is it better to get the data from the argument to the messageReceived
function or to access the vuex store?
@anthu i heard that doing this.$options
and then an assignment is not a good way to do things because $options
is read-only .. but i'm very new to vue and i don't know if this could cause problems or what is the better way to do this ...
EDIT: "this.$options is immutable but this.$options.socket.onmessage isn't"
If i start using this listener this.$options.sockets.onmessage = (data) => console.log(data)
and then access the store which has been filled with state.message = message
i'm always 1 behind with the actual data. I reopen this issue because i think this part of the library could use some best practice recommendation.
store.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
socket: {
isConnected: false,
message: '',
reconnectError: false
},
message: {
awesome: ''
}
},
mutations: {
SOCKET_ONOPEN (state, event) {
state.socket.isConnected = true
},
SOCKET_ONCLOSE (state, event) {
state.socket.isConnected = false
},
SOCKET_ONERROR (state, event) {
console.error(state, event)
},
// default handler called for all methods
SOCKET_ONMESSAGE (state, message) {
console.log('message in store', message.regs)
state.message = message
},
// mutations for reconnect methods
[WebSocket.WS_RECONNECT](state, count) {
console.info(state, count)
},
[WebSocket.WS_RECONNECT_ERROR](state) {
state.socket.reconnectError = true
}
}
})
Socket.vue
<template>
<div>
<p v-if="isConnected">We're connected to the server!</p>
<p>{{r.reg1}}</p>
<p>{{r.reg2}}</p>
<p>{{r.reg3}}</p>
<button @click="start()">start</button>
<button @click="stop()">stop</button>
</div>
</template>
<script>
export default {
data() {
return {
isConnected: false,
regnames: [],
r: []
}
},
created() {
// todo: get regnames dynamically
var regnames = ['reg1', 'reg2', 'reg3']
regnames.forEach((name) => {
this.regnames.push(name)
this.r[name] = 0
})
this.$options.sockets.onmessage = (data) => this.messageReceived(data)
},
methods: {
messageReceived: function(raw_message) {
var p = this.$store.state.message.regs
console.log(raw_message)
for (var regname in p) {
console.log(regname + ': ' + p[regname])
if (p.hasOwnProperty(regname)) {
this.r[regname] = p[regname]
}
}
this.$forceUpdate()
},
start() {
this.$socket.sendObj({command: 'start'})
},
stop() {
this.$socket.sendObj({command: 'stop'})
}
}
}
</script>
console output
Socket.vue?3af7:38 MessageEvent {isTrusted: true, data: "{"regs": {"reg1": 1, "reg2": 2, "reg3": 3}}", origin: "ws://localhost:8080", lastEventId: "", source: null, …}
store.js?a259:29 message in store {reg1: 1, reg2: 2, reg3: 3}
Socket.vue?3af7:38 MessageEvent {isTrusted: true, data: "{"regs": {"reg1": 2, "reg2": 4, "reg3": 6}}", origin: "ws://localhost:8080", lastEventId: "", source: null, …}
Socket.vue?3af7:40 reg1: 1
Socket.vue?3af7:40 reg2: 2
Socket.vue?3af7:40 reg3: 3
store.js?a259:29 message in store {reg1: 2, reg2: 4, reg3: 6}
Socket.vue?3af7:38 MessageEvent {isTrusted: true, data: "{"regs": {"reg1": 3, "reg2": 6, "reg3": 9}}", origin: "ws://localhost:8080", lastEventId: "", source: null, …}
Socket.vue?3af7:40 reg1: 2
Socket.vue?3af7:40 reg2: 4
Socket.vue?3af7:40 reg3: 6
store.js?a259:29 message in store {reg1: 3, reg2: 6, reg3: 9}
By message in store
you can see the store gets the websocket events in the right order. And by Socket.vue?3af7:38
you can see that messageReceived
is also getting the RAW websocket message in the right order. But triggering this way doesn't make the local state update to the new state which is in the store. I noticed this because i'm missing this in my console output:
Socket.vue?3af7:40 reg1: 7
Socket.vue?3af7:40 reg2: 8
Socket.vue?3af7:40 reg3: 9
index.vue?3c8f:38 Uncaught TypeError: Cannot read property 'regs' of undefined
Inside one of my vue component I am trying to add a websocket listener like this:
`... , created() {
//this.$options.sockets.onmessage = function (data) { this.messageReceived(data) }
this.$options.sockets.onmessage = data => this.messageReceived(data);
},... methods: { messageReceived(raw_message) { console.log("raw_message: " + raw_message); } } ` It works fine on chrome but not on IE11. On IE I get the following error (sorry in french):
[Vue warn]: Error in created hook: "TypeError: Impossible de définir la propriété « onmessage » d’une référence null ou non définie"
It means: Cannot define property onmessage from a null or undefined reference. First I thought it was because of arrow function but even when I try without it I have the same error. Any idea ?
@vrichomme maybe this helps:
beforeCreate() {
this.$options.sockets = {
onmessage: data => this.messageReceived(data)
}
}
How can i use
onmessage
oronopen
in my Vue component? I have vue-native-websocket and vuex already setup. I know i should use this code https://github.com/nathantsoi/vue-native-websocket#dynamic-socket-event-listeners but where?