Nhớ lại ngày xưa làm cái forum cho lớp, cứ 5 giây lại phải F5 trang để xem có đứa nào chat chit gì không, mệt thực sự. Giờ đây với Node.js và Socket.io, việc xây dựng một ứng dụng chat real-time mượt mà, không cần F5 đã trở nên dễ dàng hơn bao giờ hết. Bài viết này là kinh nghiệm thực chiến của mình tại Phạm Hải, sẽ chỉ cho bạn cách tạo một Socket.io realtime chat app Node.js đơn giản nhưng đầy đủ chức năng từ con số không, đảm bảo đọc xong là làm được ngay.
Sản phẩm cuối cùng và code hoàn chỉnh cho bạn nào “lười” đọc
Dưới đây là toàn bộ mã nguồn của ứng dụng chat thời gian thực. Bạn chỉ cần copy, dán và chạy là có ngay một sản phẩm hoàn chỉnh để vọc vạch.
Demo nhanh ứng dụng chat sẽ trông như thế nào
Ứng dụng cho phép nhiều người dùng kết nối, gửi tin nhắn và hiển thị ngay lập tức trên màn hình của tất cả mọi người mà không cần tải lại trang.
Giao diện cực kỳ tối giản với một khung hiển thị tin nhắn và một ô nhập liệu ở dưới cùng. Khi một người gõ và bấm “Gửi”, dòng text đó nảy lên màn hình của tất cả những ai đang truy cập. Đây chính là sức mạnh của giao tiếp thời gian thực. Cảm giác lần đầu tiên tự tay code ra được tính năng này thực sự rất “đã”.
Toàn bộ code phía server (file server.js)
File server.js đảm nhiệm vai trò khởi tạo server, lắng nghe kết nối và xử lý logic phát sóng (broadcasting) tin nhắn.
Mình biết nhiều bạn đang tìm code ví dụ Socket.io chat app Node.js để chạy thử luôn thay vì đọc lý thuyết dài dòng. Đây là đoạn mã Node.js kết hợp ExpressJS tối giản nhất. Nếu bạn tò mò muốn biết cách dùng Express để làm những thứ phức tạp hơn như viết API, bạn có thể xem qua bài viết Express.js tạo REST API hoàn chỉnh của mình nhé.
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('Một người dùng đã kết nối');
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
socket.on('disconnect', () => {
console.log('Người dùng đã ngắt kết nối');
});
});
server.listen(3000, () => {
console.log('Server đang chạy tại http://localhost:3000');
});
Toàn bộ code phía client (file index.html)
File index.html chứa cấu trúc HTML, CSS cơ bản và đoạn script JavaScript frontend để kết nối ngược lại server.
Ở phía client-side, chúng ta cần một giao diện để người dùng tương tác. Đoạn code dưới đây tích hợp sẵn CDN của Socket.io client. Giao diện này không có gì phức tạp, chủ yếu tập trung vào luồng gửi và nhận dữ liệu.
<!DOCTYPE html>
<html>
<head>
<title>Socket.io Chat App</title>
<style>
body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
#form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
#input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
#input:focus { outline: none; }
#form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; cursor: pointer; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages > li { padding: 0.5rem 1rem; }
#messages > li:nth-child(odd) { background: #efefef; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Gửi</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>
</body>
</html>
Hướng dẫn chạy ứng dụng trong 1 nốt nhạc
Chỉ với vài dòng lệnh terminal cơ bản, bạn đã có thể khởi động server và trải nghiệm ngay thành quả.
Bạn tạo một thư mục trống, bỏ 2 file server.js và index.html vào đó. Mở terminal lên, chạy npm init -y rồi gõ tiếp npm install express socket.io. Cuối cùng gõ node server.js. Mở trình duyệt truy cập vào Cổng http://localhost:3000 là xong. Dễ như ăn kẹo!
Bắt tay vào làm thôi! Hướng dẫn chi tiết từng bước một

Dưới đây là hướng dẫn xây dựng ứng dụng chat Socket.io Node.js từng bước để bạn hiểu rõ bản chất của từng dòng code vừa copy ở trên.
Bước 1: Chuẩn bị môi trường, cài đặt “đồ nghề” cần thiết
Khởi tạo project Node.js và cài đặt các package bắt buộc thông qua npm.
Đầu tiên, bạn cần chắc chắn máy tính đã cài đặt Node.js. Đối với những bạn mới chuyển sang làm backend, việc nắm vững nền tảng là rất quan trọng. Bạn nên tham khảo bài viết Học Node.js từ đầu cho backend developer để củng cố kiến thức trước khi đi sâu hơn. Tiếp theo, mở terminal, tạo thư mục mới và chạy npm init -y để tạo file package.json. Sau đó, thực hiện cài đặt Socket.io và Node.js cho ứng dụng chat bằng lệnh: npm install express socket.io. Quá trình này sẽ tự động tải các thư viện cần thiết qua npm về máy của bạn.
Bước 2: Dựng server Express đơn giản để phục vụ file HTML
Sử dụng Express để tạo một web server cơ bản, trả về giao diện chat cho người dùng khi họ truy cập.
Trong file index.js (hoặc server.js tùy bạn đặt tên), mình gọi thư viện Express và tạo một HTTP server. Express sẽ lo việc routing. Cụ thể là khi người dùng vào trang chủ /, server sẽ gửi trả file index.html. Đây là mô hình client-server truyền thống cơ bản nhất mà bất kỳ web dev nào cũng phải nắm vững.
Bước 3: Tích hợp Socket.io – “Trái tim” của ứng dụng chat
Gắn Socket.io vào HTTP server vừa tạo để bắt đầu lắng nghe các kết nối WebSocket.
Chỗ này mới là phần “ăn tiền” nè. Mình khởi tạo một instance của Server từ thư viện socket.io và truyền cái HTTP server vào đó. Lúc này, ở server-side, Socket.io bắt đầu lắng nghe sự kiện connection. Mỗi khi có một tab trình duyệt mở trang web của bạn, một kết nối thời gian thực mới sẽ được thiết lập thành công.
Bước 4: Xử lý giao diện người dùng và kết nối từ client
Viết mã HTML/CSS và dùng JavaScript để khởi tạo kết nối từ trình duyệt lên server.
Quay sang file index.html, bạn cần thêm thẻ <script src="/socket.io/socket.io.js"></script>. File script này được server Socket.io tự động cung cấp, bạn không cần phải tải thủ công. Sau đó, chỉ cần gọi biến const socket = io(); trong đoạn script là trình duyệt sẽ tự động tìm cách kết nối với server. Cách tạo ứng dụng chat realtime với Socket.io và Node.js thực chất bắt đầu từ dòng code nhỏ bé này.
Bước 5: Gửi và nhận tin nhắn real-time
Sử dụng các hàm emit và on để truyền tải dữ liệu qua lại giữa máy khách và máy chủ ngay lập tức.
Khi người dùng gõ tin nhắn và bấm submit, client sẽ dùng hàm socket.emit(‘chat message’, msg) để bắn dữ liệu lên server. Ở chiều ngược lại, server lắng nghe bằng socket.on(‘chat message’, …). Nhận được tin, server lập tức dùng io.emit(‘chat message’, msg) để broadcasting tin nhắn đó tới toàn bộ những người đang kết nối. Đây chính là cốt lõi của giao tiếp dựa trên sự kiện (Event-driven) giúp ứng dụng phản hồi ngay lập tức.
Giải ngố cho người mới: Socket.io là gì và tại sao nó lại “thần thánh” vậy?

Socket.io là thư viện JavaScript hỗ trợ giao tiếp hai chiều, thời gian thực và dựa trên sự kiện giữa trình duyệt và máy chủ.
Lịch sử “đau thương”: Từ Ajax Polling đến Long-Polling
Trước khi có công nghệ hiện đại, lập trình viên phải dùng các thủ thuật tốn tài nguyên để giả lập thời gian thực.
Ngày xưa, để làm chức năng chat, tụi mình hay dùng kỹ thuật Ajax Polling (cứ 3-5 giây lại gửi request lên server hỏi xem có tin mới không). Cách này cực kỳ tốn băng thông và làm chậm server. Nâng cấp hơn một chút thì có Long polling, client gửi request, server “ngâm” request đó đến khi nào có dữ liệu mới thì mới trả về. Dù đỡ hơn nhưng nó vẫn khá cồng kềnh.
WebSocket ra đời và Socket.io chính là “anh hùng”
WebSocket cung cấp một kênh kết nối liên tục, và Socket.io bọc nó lại để dễ sử dụng hơn trên mọi nền tảng trình duyệt.
Rồi giao thức WebSocket ra đời, cho phép mở một đường ống kết nối hai chiều liên tục. Tuy nhiên, việc code WebSocket thuần khá cực và dễ sinh lỗi. Thế là các bài Socket.io tutorial Node.js tiếng Việt mọc lên như nấm vì thư viện này quá tiện lợi. Nó tự động chuyển đổi (fallback) về Long-polling nếu trình duyệt của người dùng quá cũ không hỗ trợ WebSocket. Để hiểu Socket.io là gì và cách hoạt động trong chat app, bạn cứ hình dung nó là một lớp áo giáp hoàn hảo bảo vệ và tăng sức mạnh cho WebSocket.
So sánh nhanh: Socket.io vs. WebSocket thuần
Socket.io mang lại nhiều tính năng sẵn có như tự động kết nối lại, chia phòng chat, trong khi WebSocket thuần thì nhẹ hơn nhưng phải tự code tay nhiều thứ.
Dưới đây là bảng so sánh nhanh dựa trên kinh nghiệm thực tế của mình:
| Tiêu chí | WebSocket thuần | Socket.io |
|---|---|---|
| Bản chất | Chuẩn giao thức HTML5 | Thư viện bọc ngoài (Wrapper) |
| Tự động kết nối lại | Không (Phải tự viết logic) | Có sẵn, cực kỳ ổn định |
| Chia phòng (Rooms) | Tự quản lý logic phức tạp | Hỗ trợ sẵn API cực dễ dùng |
Nâng cấp ứng dụng: Thêm vài tính năng cho “pro” hơn
Một ứng dụng chat thực tế cần nhiều hơn là chỉ gửi nhận tin nhắn đơn thuần. Dưới đây là vài gợi ý để bạn mở rộng dự án.
Hiển thị thông báo “Ai đó đang gõ phím…”
Bắt sự kiện keypress trên ô input để báo cho những người khác biết có người chuẩn bị gửi tin nhắn.
Để xây dựng ứng dụng chat thời gian thực Node.js Socket.io xịn xò và giống thật hơn, bạn có thể bắt sự kiện input trên ô nhập liệu. Khi người dùng bắt đầu gõ, client sẽ emit một sự kiện tên là typing. Server nhận được sẽ broadcast sự kiện này cho các client khác (trừ người đang gõ) để hiển thị dòng chữ mờ mờ “Ai đó đang gõ…”.
Hiển thị danh sách người dùng đang online
Lưu trữ danh sách các ID đang kết nối để đếm số lượng người dùng trực tuyến trong phòng.
Khi tìm hiểu làm thế nào để tạo ứng dụng chat nhiều người dùng với Socket.io, việc biết ai đang online là tính năng bắt buộc. Bạn có thể lưu ID của các user vào một mảng (Array) hoặc Set trên server. Khi có người kết nối hoặc ngắt kết nối, server sẽ tự động cập nhật mảng này và gửi danh sách mới nhất về cho mọi người. Tính năng này đóng vai trò nền tảng khi bạn muốn phát triển hệ thống phòng chat (chat rooms) nhiều chủ đề.
Gửi tin nhắn cho một người dùng cụ thể (Private Message)
Gửi tin nhắn trực tiếp đến một socket.id duy nhất thay vì phát sóng cho toàn bộ hệ thống.
Thay vì dùng io.emit để gửi cho tất cả, bạn có thể dùng io.to(socketId).emit(...) để gửi tin nhắn riêng tư. Tuy nhiên, trong môi trường thực tế, để làm chức năng này an toàn và không bị lộ thông tin, bạn bắt buộc phải có hệ thống xác thực. Mình khuyên bạn nên áp dụng kiến thức từ bài JWT authentication Node.js bảo mật API để định danh chính xác ai đang chat với ai, từ đó hệ thống mới biết đường gửi tin nhắn đến đúng người nhận.
Vậy là bạn đã tự tay xây dựng được một Socket.io realtime chat app Node.js rồi đấy. Nhìn lại toàn bộ quá trình thì cũng không quá phức tạp phải không nào? Tại Phạm Hải, tụi mình nhận thấy công nghệ luôn thay đổi từng ngày, nhưng những kiến thức cốt lõi về kết nối thời gian thực như thế này sẽ luôn là nền tảng vững chắc. Từ bộ khung cơ bản này, bạn hoàn toàn có thể tự tin phát triển thêm nhiều tính năng hay ho khác. Chúc bạn thành công trên con đường code của mình và tạo ra những ứng dụng thật tuyệt vời!
Bạn đã chạy thử mã nguồn thành công chưa? Hãy để lại bình luận khoe thành quả bên dưới nhé. Nếu gặp bất kỳ lỗi nào trong quá trình cài đặt hay vướng mắc ở dòng code nào, đừng ngần ngại hỏi, mình sẽ hỗ trợ trả lời sớm nhất có thể!
Lưu ý: Các thông tin trong bài viết này chỉ mang tính chất tham khảo. Để có lời khuyên tốt nhất, vui lòng liên hệ trực tiếp với chúng tôi để được tư vấn cụ thể dựa trên nhu cầu thực tế của bạn.