A couple of weeks ago, I was asked to create a simple communicator for one of our clients. I had to dig deeper into the topic and I decided to create a very basic proof of concept, without all the shiny features, a straightforward chat application that implements "one-to-many" communication. I wanted to use technology that I already knew, so the client application was created in Vue.js using Vue-cli 3, and the server was created in Node.js. For development purposes, I used the Express web server, which is flexible and fast, just enough for MVP. What I’d like to show you is how fast we can achieve this goal in terms of configuration and coding.
Getting started
Let's start with our server. I assume we already have Node.js and package manager like Npm or Yarn, I will be using Yarn in this example. All we really need is two packages, let's get them:
Now, add a new `server.js` file, where we will create a new instance of the Express server.
At the beginning of the snippet, we include two previously installed packages, then we create a new instance of the Express server in our constructor that will listen to localhost communication on port 8081. We don't need to specify the port, Express will automatically choose a free port for us. However, in this case we want to explicitly set the port for our server, so that it stays the same all the time. Finally, we hook up Socket.io to our server with the io() function. At this point, the server doesn't do anything spectacular, it's only listening to connections.
We can start the server by running:
Let's now jump to our client application. First, we need to globally install Vue-cli:
Now, we can create a new application by typing:
We will be asked to pick up a preset, I chose the default babel, eslint. Our project will be set up and we can run it by typing:
We will also need the Socket.io package for the client, we can add it by typing:
I personally like working with sass, so I additionally added two packages required to write scss code in the Vue environment:
At this point, we are ready for some serious coding. Let's get straight into it!
Diving deeper into the server
Now, we need to create a new file with all the listeners. I created three events that are passed from our client to the server:
- connected we store user data and emit a users event that keeps all users data for all connected clients
- disconnect we remove a user from users object and also emit a users event to update clients
- message we inform all connected clients about a new message that has been sent
Here is what I ended up with:
Now, we need to add our events to the server.js file, as below:
Also, we should evoke the constructor, passing our socket object, and then trigger the eventsConfig function:
so that the final server.js file looks like this:
That is all we need for the server application.
Client application
For our client application, I created three components:
- ChatUserList.vue for keeping chat participants list
- ChatConversation.vue for keeping all chat messages
- App.vue that binds everything together
ChatUserList.vue
It consist of a simple “for” loop with users, and when a component is mounted we also create two listeners users and disconnect that will react to events emitted by the server. We must pass a socket object as a property to this component, as soon as the socket is created. This is what the file looks like in its final shape:
ChatConversation.vue
App.vue
This is the most important part of the client application. First of all, it ties up our components, but what is more important we create a connection to our server. When the component is created, we call the native javascript function prompt() and ask for a username.
When the username is provided, we create a connection to the server and broadcast the connect event. The server can respond to it and broadcast the new user list that needs to be updated to all users. After the username is provided and we connected to the server, the chat window is displayed. At the bottom, there is a text input that will transport our message to the server and a send button. Additionally, I handled the enter key event so that the messages can be sent either by pressing the enter key or by clicking the send button.
Before the component is destroyed, we broadcast a disconnected event in order to let the server know that we are no longer connected and it's the right time to update other users with that information.
And that is pretty much it. As you can see, it's straightforward and self-explanatory. I hope that after reading this article you will be able to create something even more fascinating using the Socket.io library. Here are two GitHub repositories with the client and server applications, check them out and feel free to ask me any questions at marcin.kunysz@fingo.pl