Building a Real-Time Chat App with Node.js and Socket.IO: A Step-by-Step Guide
1. Understanding the Basics
Before diving into the code, let's understand the basics. Node.js, known for its scalability and efficiency, will serve as the backend for our chat application. Socket.IO, a JavaScript library, will be our go-to tool for enabling real-time, bidirectional communication between the server and the clients. Together, they form a powerful stack for building responsive and interactive applications.
2. Setting Up Your Node.js Environment
Let's kick off the development process by setting up a Node.js environment. If you haven't already, install Node.js on your machine. Create a new project folder, initiate a package.json file, and install the necessary dependencies, including Express and Socket.IO.
npm init -y
yarn add express
yarn add socket.io
or copy the file package.json
and run yarn install
{
"name": "hion-chat",
"version": "1.0.0",
"description": "For demo",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"socket.io": "^4.7.2"
},
"type": "module"
}
Structure project:
3. Creating the NodeJS Server
The main control file here is server.js
, this file will be the file that runs when running node:
import express from "express";
import { createServer } from "http";
import { Server } from "socket.io";
import { dirname } from "path";
import { fileURLToPath } from "url";
import cors from "cors";
const app = express();
const http = createServer(app);
const io = new Server(http, {
cors: {
origin: "http://localhost:3000",
methods: ["*"],
},
});
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Headers", "Content-Type");
res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
next();
});
const corsOrigin = {
origin: "http://localhost:3000",
credentials: true,
optionSuccessStatus: 200,
};
app.use(cors(corsOrigin));
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
io.on("connection", (socket) => {
console.log("A user connected");
socket.on("chat-message", (message) => {
console.log(message);
io.emit("chat-message", message);
});
socket.on("disconnect", () => {
console.log("A user disconnected");
});
});
http.listen(3001, () => {
console.log("Server is running on port 3001");
});
Run the file server by command:
yarn start
4. Building the Frontend with HTML and Socket.IO Client
For the front end, we'll keep it simple with HTML and use the Socket.IO client to handle real-time communication. Create a index.html
file with the following structure:
<html>
<head>
<title>Socket.IO chat</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</head>
<body>
<label for="message" class="h4" style="margin-top: 20px;">Message:</label>
<ul id="messages" style="height: 600px; border: solid 1px #cecece;"></ul>
<form action="">
<div class="form-group">
<textarea id="message" class="form-control" rows="5" placeholder="Enter your message" required></textarea>
</div>
<button type="submit" id="form-submit" class="btn btn-success btn-lg pull-right ">Submit</button>
</form>
</body>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
console.log(socket)
socket.on("connect", () => {
console.log("connect", socket.id);
});
$('form').submit(function () {
socket.emit('chat-message', $('#message').val());
$('#message').val('');
return false;
});
socket.on('chat-message', function (msg) {
$('#messages').append($('<li>').text(msg));
});
});
</script>
</html>
5. Run Your Real-Time Chat App
With your Node.js server running (node server.js), open your browser and navigate to http://localhost:3001
. You should witness the magic of real-time communication as messages flow seamlessly between connected clients.