Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrate SignalR with Vue.js and Vuex

Tags:

We are currently working on a voting app based on the vue-cli webpack template. Since we want to store and manipulate our voting state in a consistent and maintainable fashion we intend to use vuex for state management. The interaction between frontend and backend is based on websockets and we want to use signalr since it has been proven very good in previous projects. Due to the fact that we are new to vue.js we need some advice how to integrate signalr, vuex and vue.js perfectly together.

Let's describe the scenario:

The frontend gets an event from our backend to recognize, that the voting poll is active and can receive the selected answers. After a period of time we inform the frontend that results are available and display them to the user. In some cases we might open another voting poll. It is important that we are able to disconnect in case the document gets hidden (page visibility api).

Our solution approach:

In general I'd like to implement a special signal.service for this purposes. This service is responsible for establishing the connection as well as sending and receiving the messages via websockets. Since we are not able to perform any changes to vuex store from a common module, we figured out that a vuex plugin would be suitable. The vuex plugin should wrap signalr.

In case we receive a VotingStartEvent we would unlock the respective question and display it to the user. If the user answered that question we commit the new state of this question (answered) to the vuex store. Inside our plugin we have a subscription to mutations and we would use this subscription to send our vote to the backend. The following snippet illustrates the idea:

var plugin = (store) => {
  // ...
  store.subscribe((mutation, state) => {
    console.log('inside subscription');
    // if vote has answered state, call connection.send() to submit the message to the backend
  });

  connection.received((message) => {
    // ...
    var event = parseEvent(message);
    if (event.type === START) {
      store.commit({type: 'voting', item: 'unlocked'});
    }
    // ...
  });
}

Is this approach good or do you see any room for improvement?