- Lab
- Core Tech

Guided: Build a Simple Chat Server in Node.js
In this Guided Code Lab, you'll implement a chat server using Node.js and Socket.io, focusing on essential functionalities. You will set up connections, integrate authentication, handle user statuses, and enable private, group messaging, and file transfers. In this lab, you'll channel your coding expertise into the practical development of a real-time chat server, emphasizing hands-on experience with communication technology.

Path Info
Table of Contents
-
Challenge
Introduction
In this Guided Code Lab, you're going to bring to life Globochat, a chat application built with Node.js. Your journey will involve implementing key functionalities that are essential to any chat application. This includes displaying a list of users, enabling private messaging, and facilitating group chats.
While Globochat is set up to run in its initial state, it's up to you to breathe life into it. You'll do this by configuring real-time communication channels.
The frontend side for this chat has already been implemented. You will only be working on the server side to add various missing functionalities.
Getting Started
Follow these simple steps to get your version of Globochat up and running:
- Launch the Application: In the Terminal run the command
npm start
. This will start the Globochat server. - Access the Chat Interface: Once the server is up and running, access the chat interface by clicking on the following link: {{localhost:3000}}. You are going to be presented with the login screen. Use any of the usernames in the list to log-in.
- Once you log-in you should see a list of users available for messaging. The list of users will show everyone except the currently logged-in user, which will be yourself. Sending messages will not work at this stage because the real-time messaging capabilities are not added and will be configured as you move along with the steps.
info> Keep in mind:
- As you make changes to the server-side code, remember that the application must be stopped and restarted for these changes to take effect. This is crucial for testing and validating the new functionalities you implement.
- There is asolution
directory in the Filetree that you can look at if you get stuck. - Launch the Application: In the Terminal run the command
-
Challenge
Setting Up Web Sockets
In the realm of real-time messaging, the ability to send and receive messages swiftly and seamlessly is paramount. This is typically achieved through WebSockets, a technology enabling continuous two-way communication between your browser and the server.
However, implementing WebSockets from scratch can be intricate and challenging. This is where Socket.io, a renowned library in the Node.js landscape, becomes essential. It greatly simplifies the creation and management of WebSocket connections.
For your chat application, Socket.io stands as a highly recommended choice. It's a popular library, celebrated for its ease of use and efficiency in handling WebSocket communications. By utilizing Socket.io, you can establish robust real-time communication channels for your application, enhancing the chat experience without dealing with the complexities of raw WebSocket management. This focus on simplicity and effectiveness makes Socket.io a valuable asset in developing your real-time messaging features.
Introducing WebSockets to Your API
Now it's time to integrate WebSockets into your API. This will bring your application to life by allowing real-time communication between users.
Getting Started with Socket.io
You'll be working within the
server/chat.js
file to configure and set up Socket.io, where you are going to be receiving and sending messages in real-time between your server and connected clients.Now that you have established a connection between the frontend and backend for real-time communication you need to add authentication.
When a user connection is made that connection will have an authentication token passed. A middleware needs to be integrated into the Socket.io configuration to determine if the current user is logged in. If the user is not logged in, the connection is terminated. Users need to know the status of each other when messaging. Whenever a user connects you need to broadcast a message to all listening clients with the status of the user indicating they are online. Your next task is to emit a message when a user is connected to broadcast the user's online status. Just like a user connects, a user also disconnect when they close their browser. Once the user disconnects you need to update the user's status as well to indicate they are now offline.
Your next task is to handle user disconnect by updating the user status to offline and emitting a message to all users to inform them about their status. Congratulations, you are all done with setting up Socket.io and broadcasting your first message to connected clients. Now users can log-in and see who is online before messaging each other.
To test this properly open two browser tabs. One normal and one incognito, alternatively you can open this these tabs in two different browsers. In each of the tabs login as a different user and you should see the status of the logged-in users as being online indicated by a green dot next to their name.
Next, you will setup private messaging between two users so they can chat in real-time.
-
Challenge
One-to-one Messaging
A user can connect from multiple devices and messages need to be sent to all of these devices. To achieve this, you will need a method to track all socket connections for specific users, ensuring messages are directed to the correct recipients when someone sends a message.
To keep track of connections for a user, you will be using rooms. Whenever a user connects, you will add that connection to a room and the room name will be the user's username to keep it simple. You'll be using rooms because they provide a simple and convenient method to manage all connections and facilitate sending messages to a group without needing to keep track of which connection belongs to which user. Now that you have the user join their personal room when connected, it is time to send messages between users.
Before you can broadcast messages, first you need to add an event listener that will receive messages and store them somewhere.
The event listener is needed to receive messages. For storage you are going to store them in an in-memory database that will be provided for you. You have added the ability for the frontend to send you messages and you are storing them in the database.
If you try to send a message to one of the users on your list, you will notice that the message will not show anywhere. Although after sending the message, if you refresh the page and open that chat, the message will appear. That's because, up until now, you only receive the message on the server and store it in the database.
Your next step will be to broadcast the newly received message to sender and receiver so the frontend can be updated in real-time.
info> Tip: The message should be sent to the sender and the receiver so the frontend updates it automatically on all instances that they are connected from. So the message needs to be sent to the senders room and the receivers room. Well done! You have successfully implemented one-to-one messaging between two individual users.
To try this out open two separate browser tabs. One of the tabs has to be incognito and login with separate users. As soon as you send a message the messages should appear live for both users.
Next you are going to setup group messaging for your chat application.
-
Challenge
Group Messaging
Congratulations you have finished one-to-one messaging between two users.
Now its time to implement group messaging. Instead of sending the message to one person you are going to send the message to a group of people.
By default when the application starts it creates a group called Everyone Group that has all the users inside. Using the frontend you have an API that allows you to create new group and select the people that will be part of it.
Your next task is to create a room with the group id and add the users' socket connections to that room for sending messages.
Creating a room for a group and adding all connections from users that belong to that group will allow you to easily broadcast a message to all group users. Now that you have the all the users of a group join the group room when connecting, it is time to send messages between groups.
Before you can broadcast messages, you need to add an event listener that will receive messages and store them somewhere. The event listener is needed to receive messages. For storage, you are going to store them in the in-memory groups database that will be provided for you. You are almost done! Now that the messages for the group are being received and stored, it is time to broadcast them so the frontend can update in real-time.
You need to broadcast the messages to a room that has the group's id as the name. For the payload, use the newly created group message. The reason why you broadcast to just one room instead of two rooms, like you did for private messaging, is because all users that are part of the group have been added to this room. This ensures that everyone will receive the message.
Congratulations you have successfully implemented group chats for your application.
You can test this by logging in from two different browser tabs with separate users. In the left your should have a group named
EveryoneGroup
if you send a message in there all users should receive that message.Next you are going to add the ability to send files to your chat application.
-
Challenge
Transfering Files
In modern chat applications, the functionality to send files is essential, and your application is no exception.
There are a couple of methods to implement file transfers: using WebSockets or a dedicated API for file uploads. WebSockets, while efficient for small files, are not ideal for larger file transfers due to potential performance limitations. For sending larger files, a specialized API for file uploads is recommended.
In this Guided Code Lab, you will focus primarily on WebSocket technology. You'll implement file transfer using Socket.io. This approach is particularly suitable for smaller files, allowing your chat application to facilitate file sharing seamlessly within the real-time communication framework provided by Socket.io.
Your next task is to create an event listener that will receive the file and store it. Now that you have received and stored the file, it's time to notify the intended user that they have a new message.
After successfully uploading and storing the file, you will need to add a message to the database and notify both the sender and the receiver about the new message.
Well done! You have implemented receiving messages, storing, and broadcasting the newly received messages to the intended parties.
Now for the icing on the cake you are going to take it one step further to provide a better user experience.
As you know network connections can be unpredictable and slow sometimes. Although your file transfer mechanism is intended for small files, uploading these files can take a couple of seconds depending on the Internet connection.
To provide a better user experience the server should acknowledge that the file was received successfully or failed to process. To implement this, when a file is uploaded, the server should send the following message indicating successful processing.
This is needed to provide feedback to clients regarding whether the file was successfully received or not. Additionally, it allows frontend applications to display a loading indicator to users while the file is being sent, particularly if sending takes a long time.
info> Tip: To send an acknowledgment with Socket.io, include a callback when defining the event listener after the payload. Once you have the acknowledgment callback function, call it after processing the file to notify the client that sent the message.
socket.on('privatefileupload', ({data,name,to},ackCallback)=> { fs.writeFile(`uploads/${name}`, buffer, (err) => { if (err) { ackCallback({ success: false, message: 'Failed to process file' }); } else { ackCallback({ success: true, message: 'File uploaded successfully' }); //rest of the code } }); }); ``` Congratulations! You have successfully implemented a file transfer mechanism within your chat application. To test this, start the application and use the upload file functionality on one-to-one chats in the user interface. As soon as you send a file, the message that appears will not be a regular message; instead, it will indicate that it's an attachment. The current functionality of the frontend is limited to displaying that the message is an attachment. There is no download functionality implemented, which is beyond the scope of this Guided Code Lab. info> **Tip**: To ensure the acknowledgment function works with Socket.io, the client connection must specify it. If the emitting client doesn't specify a callback function, the `ackCallback` function you implemented will be null, as it wasn't specified by the sending client. To enhance your chat app further, you could check if the callback function is provided, and if not, refrain from calling it.
-
Challenge
Summary
Congratulations! You have successfully implemented your first simple chat server using Node.js.
Through this Guided Code Lab, you implemented the major components that make up a chat server:
- Initializing a Socket.io Server
- Adding Authentication to Socket Connections
- Broadcasting Messages
- Creating Private User Rooms
- Creating Group Chat Rooms
- Broadcasting Messages to Rooms
- Receiving and Processing Files
If you want to take your chat application further, you could also try implementing the frontend side of the application. This Guided Code Lab focused on the server side and the frontend was already provided using
petite-vue
.petite-vue
is an alternative distribution of Vue optimized for progressive enhancement. It provides the same template syntax and reactivity mental model as standard Vue. However, it is specifically optimized for "sprinkling" a small amount of interactions on an existing HTML page rendered by a server framework.The logic for the frontend can be found in
public/index.html
. If you are familiar with Vue.js, you can use it to build your own frontend client for the chat server developed in this Guided Code Lab. Alternatively, you can opt for a frontend framework of your choice, as most of the logic will remain the same.- You will need to have a login screen to authenticate with the API.
- Connect to the Socket.io server and pass in the authentication token you get from the API.
- A list of users, groups, and messages can be retrieved from the API once you are authenticated.
- To finalize the implementation of the chat functionality, listen for events from the server such as
privatemessage
,groupmessage
, oronlinestatus
, and update the user interface accordingly. Additionally, send messages to the event listeners defined on the server.
This will give you a better end-to-end understanding on how a real-time application works by implementing both sides.
You can extend the server-side functionality by adding additional API endpoints. For example, you could implement an API endpoint to download file attachments that are sent to the server. Currently, the user interface only displays the message and indicates that it's an attachment. By adding this endpoint, the user interface can download the actual file, enhancing the user experience.
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.