nathantsoi / vue-native-websocket

native websocket with vuex integration
943 stars 162 forks source link

Send message from within Vuex actions #13

Open moritzsternemann opened 7 years ago

moritzsternemann commented 7 years ago

Is there a way to send websocket messages from within my Vuex actions?

emerika commented 7 years ago

I have the same issue. When I connect, I need to immediately send a message to open a session. I can't figure out how to make the call from inside SOCKET_ONOPEN.

emerika commented 7 years ago

I think you can do this: event.sendObj({x:'something'}) however, I don't seem to be getting messages so it's hard to know

crholliday commented 7 years ago

I have a similar issue. How can you send a message from a vue instance? I have a KPI tile component that will "subscribe" to a specific market ticker. To do this i compile a JSON object and send it to the socket which will then start sending messages back about that ticker. Can't figure it out...

deyunote commented 7 years ago

Hi there. There is a snippet to use Websocket instance within Vuex actions/mutations. (I dont consider side effects from this code)

In your entry point

import Vue from "vue"
import VueWebsocket from "vue-native-websocket"
import store from "./your_vuex_store"

Vue.use(VueWebsocket, "ws://example.com", {store})
store.$socket = Vue.prototype.$socket 
//https://github.com/nathantsoi/vue-native-websocket/blob/master/src/Main.js#L11

and in your vuex actions

actions: {
  sendSomething(context, {data}) {
    this.$socket.send(data)
  }
}
emerika commented 7 years ago

This worked for me -- however, I wasn't able to send any json messages if I used: Vue.use(VueWebsocket, "ws://example.com", {store, format: 'json'}) could be pilot error

however, if I removed the "format: 'json'" and did this when sending: var os = JSON.stringify({ 'msg_id': state.sequence++, 'msg_type' : 'open_connect', 'content': { 'site': 'DFD', 'user_agent': 'GHSS' } }) this.$socket.send(os) it worked.

I tried the sendObj call thus: sendObj({var1: 'sds', var2: 'sdsdsdsdsd'}) and I could not get it to work -- again probably pilot error

deyunote commented 7 years ago

Hi @emerika Did you get error messages?

emerika commented 7 years ago

No errors -- Inside the inspector->network I could see that nothing was being sent -- It may very well have been something I did wrong.

ThomasKlessen commented 6 years ago

@emerika : I think this is desired behavior. If you use format: 'json' option the code enforces strict usage of sendObj. And viceversa; If you don't use json format then there is only the send function.

shurochkin commented 6 years ago

Hi, i have problem.

main.js

import Vue from "vue"
import VueWebsocket from "vue-native-websocket"
import store from "./store"
Vue.use(VueNativeSock, url, { store, format: 'json', reconnection: false })
store.$socket = Vue.prototype.$socket

store.js

actions: {
    getData() {
      this.$socket.sendObj({action: 'getData'})
    }
}

And I see error in DevTools: DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.

What am I doing wrong?

ThomasKlessen commented 6 years ago

You need to wait for SOCKET_ONOPEN Event. After that you can send with your provided code.

One way to achieve this could be:

this.$store.subscribe((mutation, state) => {
      if (mutation.type === 'SOCKET_ONOPEN' ) {
           // your code here
      }
}
pieterjandesmedt commented 6 years ago

You could also set an interval to check if the socket is connected:

const mutations = {
    SOCKET_ONOPEN(state, event) {
        console.log('SOCKET_ONOPEN event', event);
        state.socket.isConnected = true;
    },
// ....
    socketSend(state, message) {
        if (state.socket.isConnected) {
            this.$socket.sendObj(message);
        } else {
            const self = this;
            const intervalId = setInterval(() => {
                if (state.socket.isConnected) {
                    self.$socket.sendObj(message);
                    clearInterval(intervalId);
                }
            }, 1000);
        }
    }
};
morfair commented 3 years ago

store.$socket = Vue.prototype.$socket

and

actions: {
  sendSomething(context, {data}) {
    this.$socket.send(data)
  }
}

not work after WebSocket reconnected