Đã bao giờ bạn nhắn tin và kinh ngạc khi tin nhắn đến với tốc độ ánh sáng? Đó là nhờ các công nghệ truyền thông siêu thời gian thực như WebSocket! Bạn không cần phải làm việc ở một công ty công nghệ lớn hay nắm kỹ thuật phức tạp mới có thể xây dựng một ứng dụng chat nhanh như Messenger hay WhatsApp. Trong bài viết này, mình sẽ hướng dẫn bạn, dù là coder "entry-level" hay lập trình viên kinh nghiệm, cách xây dựng một ứng dụng chat sử dụng WebSocket — vừa đơn giản, vừa mạnh mẽ. Cùng khám phá từ lý thuyết đến thực hành nhé!
Trước khi bắt tay vào xây dựng, hãy làm rõ: WebSocket là gì và tại sao được đánh giá là "siêu thời gian thực". Đối với những ai quen thuộc với HTTP, sẽ biết mô hình hoạt động của nó là dạng truy vấn — client gửi request, server phản hồi. Điều này phù hợp với các website tĩnh, nhưng đối với các ứng dụng chat thì lại gây trễ.
WebSocket là một giao thức mạng cho phép hai chiều truyền dữ liệu liên tục trong một kết nối duy nhất, không cần phải "xin phép" gửi từng vòng như HTTP. Điều khiến WebSocket nổi bật là:
Ứng dụng thường dùng WebSocket gồm: chat room, game đa người chơi, thực thi lệnh tài chính, theo dõi dữ liệu "live" (giá chứng khoán...).
Trước khi code, hãy xác định cấu trúc của một chat app đơn giản sử dụng WebSocket gồm có:
Chúng ta sẽ xây dựng một minimal chat app gồm:
Có rất nhiều ‘stack’ hiện đại cho WebSocket, nhưng để mọi người đều theo kịp, mình chọn Node.js ở phía server (với gói ws cực đơn giản, nhẹ) và client web dùng HTML, JavaScript thuần. Tại sao chọn combo này?
Tất nhiên, trong "production", bạn có thể mở rộng lên React, Vue hoặc server bằng socket.io, Go, Elixir... Nhưng với mục tiêu hiểu bản chất, let's start simple!
Đầu tiên, hãy bắt đầu với vài dòng code dựng nên cái "nòng cốt" của ứng dụng: server WebSocket.
mkdir websocket-chat-demo
cd websocket-chat-demo
npm init -y
npm install ws
server.js như sau:// server.js
const WebSocket = require('ws');
const PORT = 8080;
const wss = new WebSocket.Server({ port: PORT });
console.log(`WebSocket server đang chạy ở ws://localhost:${PORT}`);
wss.on('connection', (ws) => {
ws.on('message', (data) => {
// Khi nhận tin nhắn, chuyển nó tới các client khác
wss.clients.forEach((client) => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
ws.on('close', () => {
// (Có thể thêm xử lý khi client rời khỏi)
});
});
wss.on('connection'...) lắng nghe mỗi khi client kết nối.ws.on('message', ...) nhận message từ 1 client, chuyển tiếp cho các client còn lại.
Server đã xong, chuyển sang xây dựng phần giao diện và logic xử lý phía client.
Tạo tệp index.html với mã nguồn sau:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>WebSocket Chat Demo</title>
<style>
body { background: #f7f7f7; font-family: sans-serif; }
#chat { width: 400px; margin: 40px auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px #bbb; }
#messages { height: 220px; overflow-y: auto; border: 1px solid #ddd; margin-bottom: 15px; padding: 8px; border-radius: 4px; background:#fbfbfb; }
#messages div { margin-bottom: 8px; }
input[type="text"] { width: calc(100% - 80px); padding: 8px; border: 1px solid #bbb; border-radius: 4px; }
button { padding: 8px 14px; border: none; background: #3498db; color: white; border-radius: 4px; cursor: pointer; }
#nick-modal { position: fixed; left:0;top:0;width:100%;height:100%; z-index:999; background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center; }
#nick-modal input { width:220px; padding:8px; border-radius:4px;border:1px solid #aaa; }
</style>
</head>
<body>
<div id="chat">
<div id="messages"></div>
<form id="chat-form">
<input type="text" id="msg-input" autocomplete="off" placeholder="Nhập tin nhắn..." required />
<button type="submit">Gửi</button>
</form>
</div>
<div id="nick-modal">
<form id="nick-form">
<input type="text" id="nickname" placeholder="Nhập tên bạn..." required />
<button type="submit">OK</button>
</form>
</div>
<script>
let socket, nickname;
// Hiện modal yêu cầu nhập tên
const nickModal = document.getElementById('nick-modal');
document.getElementById('nick-form').addEventListener('submit', function(e) {
e.preventDefault();
nickname = document.getElementById('nickname').value.trim();
if(!nickname) return;
nickModal.style.display = 'none';
startChat();
});
// Khởi tạo socket, lắng nghe/gửi tin nhắn
function startChat() {
socket = new WebSocket('ws://localhost:8080');
const messages = document.getElementById('messages');
socket.addEventListener('message', function(event) {
const data = JSON.parse(event.data);
const div = document.createElement('div');
div.innerHTML = `<strong>${data.nick}</strong>: ${data.msg}`;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
});
document.getElementById('chat-form').addEventListener('submit', function(e) {
e.preventDefault();
const msgInput = document.getElementById('msg-input');
const msg = msgInput.value.trim();
if(!msg) return;
// gửi message tới server dưới dạng JSON
socket.send(JSON.stringify({ nick: nickname, msg: msg }));
// tự hiện luôn message của bản thân
const div = document.createElement('div');
div.innerHTML = `<strong style='color:#20a;'>${nickname} (bạn)</strong>: ${msg}`;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
msgInput.value = '';
});
}
</script>
</body>
</html>
nick, msg.
Dù chỉ với vài dòng code, bản chat app này lại đem lại trải nghiệm gần tương đương nhiều nền tảng chat phổ biến. Điểm mấu chốt:
Will you notice that "delay" in real-world? Nếu deploy lên server thực tế vẫn thấy tín hiệu cực nhạy. Đây chính là cái sức mạnh hấp dẫn mà các doanh nghiệp lớn lẫn startup ưa chuộng WebSocket.
| Giao thức | Vòng Truyền | Tốc độ | Tài nguyên | Thực tiễn chat app |
|---|---|---|---|---|
| HTTP Polling | Nhiều vòng | Chậm | Cao | Không thực tế |
| Long Polling | Gần real-time | Trung bình | Cao | Chấp nhận được |
| WebSocket | Hai chiều liên tục | Siêu nhanh | Thấp | Xu hướng chủ đạo |
Bạn đã hiểu được “core technology”, vậy muốn nâng app lên mức production cần làm gì?
Trước khi cho sản phẩm áp dụng thực tế, đừng quên:
Việc tự tay xây dựng app nhỏ xíu nhưng "mạnh" như WebSocket chat là cách cực tốt để: hiểu đúng bản chất công nghệ, khám phá giới hạn của frontend/backend và khai phá thêm các kỹ năng thật sự trong ngành. Đừng ngại vọc code, thử nghiệm hoặc "quậy phá" các thiết kế/giao diện mới.
Tóm lại, WebSocket là bạn đồng hành đắc lực để xây dựng mọi hệ thống thời gian thực hiện đại, nhất là khi bạn ưu tiên tốc độ, trải nghiệm và hiệu quả tài nguyên. Nếu bạn đã vững nền tảng rồi, hãy nâng cấp lên mô hình "Chat as a Service", hỗ trợ đa nền tảng, hoặc thậm chí cắm AI Chatbot vào nữa cho app thêm phần thú vị!
Vẫn chờ đón các phiên bản "super chat" tiếp theo từ bạn sau Series này nhé 🚀