Weekend Project (Part 4): Integrating Websockets into a Real-Time Vue App with Socket.io and Vuex

Josh Porter
Hacker Valley Studio
4 min readApr 23, 2018

If you’re just now tuning in, be sure to read Part 1,Part 2, and Part 3.

If you’ve read the first few parts of this series, you now should have a solid understanding of the steps needed to build a stateful and reactive app using Vue and Vuex. You should also have a websocket-enabled Flask server eager to start communicating with a client in real-time using Flask-SocketIO. We’re just missing one piece — the fabric with which to connect Vue to our server.

Diagram comparing AJAX to Websockets

Setting up a SocketIO client is as easy as initializing the connection, setting up a listener, and emitting an event. It is not required to emit an event in order to begin receiving messages — a consumer can simply connect and listen to begin utilizing the websocket as long as the server is emitting events. However, it is typical for our client to send messages to our server, and that is where emitting events come into play. If we try to compare this to a RESTful model, the emitted event is similar to a GET or a POST, and the event consumed by the listener can be similar to our response. Of course, these two systems cannot be compared directly since websockets allow our server to push messages to our client, and our client can send a message to a server with no response. Websockets is a great alternative to REST in certain circumstances, but REST still has its place in a standard resource model.

Vue + Vuex ❤ SocketIO

Getting Vue, or Javascript in general, to talk to our Flask-SocketIO server is as easy as importing the SocketIO JS client and configuring our connection. In a standard Vue project, we’d have to configure this client in one of our lifecycle events such as created and then configure some listeners and emitters. Fortunately, the Vue-Socket.IO Vue plugin exists to help streamline this process. This library adds the lifecycle hooks for us for registering listeners, and supports integration with Vuex to pipe our socket messages straight into our centralized state manager. To get started, we will have to install this package.

npm install vue-socket.io --save

In the main.js file, import the Socket.IO client and configure the plugin with the connection URL and our Vuex store.

Integrating Vue-SocketIO with Vue and Vuex

In this example, the connection URL will use the same host as window. So if we are running the dev server on http://localhost:8080, our client will attempt to connect to that host. Since we are passing our Vuex store variable to the plugin initializer, Vue-SocketIO will sink its teeth into our store and allow for dynamic listeners based on mutation names. We will go into more detail on this soon.

Usage in Vue Components

When we ran Vue.use(VueSocketio, `//${window.location.host}`, store) one important thing happened — the plugin extended the Vue prototype chain and made its socket object globally accessible. This allows us to easily emit events from anywhere in our Vue project by calling this.$socket.emit. The following example demonstrates this with a button that emits a message.

As you can see, sending a message to our server required only one extra line thanks to the global socket instance.

Receiving Messages

Now that our client can talk to our server, we also want it to listen for incoming messages. Similar to our standard websocket example, we just need to set up a listener with our SocketIO client. Let’s build upon the example above and listen on the same channel for the server’s response.

SocketIO listener integrated with Vue component

First, we have to initialize the listener — this is done in the created lifecycle hook so as soon as our component is created, it will begin listening. We then a key on the this.$options.sockets object to a callback function. This sockets object tracks all of our listeners. Under the hood, Vue-SocketIO reads all of the values in this object and registers listeners. Similarly, when a listener is deleted, it unregisters the listener.

Adding Vuex to the Mix

Setting up listeners like this is great for a simple project or one-off listeners. However, what if we want to use this data in multiple components? The typical answer is “Use Vuex” — but to use Vuex we’d have to set up listeners and use mutations and actions to store the data, right? Wrong. Vue-SocketIO makes it simple to integrate our socket responses with our central state.

Since we passed our store variable to the plugin initializer, Vue-SocketIO easily handles socket events and can automate the storage of data into Vuex.

Registering a listener using Vuex is as simple as adding a mutation prefixed with SOCKET_. The text after this prefix is the name of our channel we want to listen to. To convert the listener from our previous example, which listened on the channel hello_world, we simply create a mutation named SOCKET_HELLO_WORLD. Our server’s response to our message can now be shared with our other components!

Conclusion

Any application that requires real-time communication between the client and server can be elevated by using websockets. SocketIO streamlines this process and provides additional functionality over raw websockets. Integrating it into a Vue application can seem complex and daunting, but it is simplified thanks to Vue-SocketIO, which allows us to easily connect our server to our Vuex store with just a couple of lines of code.

Thanks for reading along, and hopefully you can apply this series to your own projects and create a real-time app using Vue!

Support Us

  • Give this post some claps 👏👏👏👏
  • Give this post some feedback in the comments
  • Join our Slack channel
  • Follow us on Facebook, Twitter, Reddit

--

--

Josh Porter
Hacker Valley Studio

Baltimore-based software developer with a passion for clean code, craft beer, and video games. http://codecaffeinated.com