Trong thời đại công nghệ số hiện nay, giao tiếp thời gian thực giữa các ứng dụng web đã trở thành một yếu tố quan trọng trong việc cung cấp trải nghiệm người dùng mượt mà và tương tác. WebSocket, một giao thức mạnh mẽ được thiết kế để tạo kết nối hai chiều giữa máy khách và máy chủ, đóng vai trò quan trọng trong việc phát triển các ứng dụng web hiện đại, từ trò chơi trực tuyến cho đến các nền tảng nhắn tin. Bài viết này sẽ giúp bạn hiểu rõ hơn về WebSocket, cách hoạt động của nó và cung cấp một ví dụ thực tế để bạn có thể áp dụng ngay vào dự án của mình.
Web socket là gì?
WebSocket là một giao thức mạng cho phép giao tiếp hai chiều giữa máy khách (client) và máy chủ (server) trên một kết nối duy nhất. Nó được thiết kế để cung cấp một kênh giao tiếp liên tục, có thể truyền tải dữ liệu mà không cần phải tạo một kết nối mới cho mỗi yêu cầu, như trong giao thức HTTP truyền thống.
Cách hoạt động của WebSocket
- Thiết lập kết nối: Kết nối WebSocket bắt đầu bằng một yêu cầu HTTP từ máy khách đến máy chủ với một header đặc biệt. Nếu máy chủ hỗ trợ WebSocket, nó sẽ trả lời bằng mã trạng thái 101 (Switching Protocols), cho phép kết nối chuyển sang giao thức WebSocket.
- Kết nối duy trì: Sau khi kết nối được thiết lập, máy khách và máy chủ có thể gửi và nhận tin nhắn trong suốt thời gian kết nối tồn tại mà không cần tái thiết lập kết nối. Kết nối này sẽ duy trì cho đến khi một trong hai bên (máy khách hoặc máy chủ) quyết định đóng nó.
- Giao tiếp hai chiều: WebSocket cho phép cả máy khách và máy chủ gửi dữ liệu đến nhau bất kỳ lúc nào, điều này khác biệt với mô hình yêu cầu-đáp truyền thống của HTTP, nơi mà máy khách phải gửi yêu cầu trước khi nhận được phản hồi.
Ưu điểm của WebSocket
- Thời gian thực: WebSocket lý tưởng cho các ứng dụng cần cập nhật dữ liệu liên tục trong thời gian thực, như trò chơi trực tuyến, ứng dụng nhắn tin, hoặc các dịch vụ tài chính.
- Giảm tải băng thông: Bằng cách giữ kết nối mở, WebSocket giảm thiểu chi phí và thời gian cho việc thiết lập lại kết nối, giúp tiết kiệm băng thông.
- Tối ưu hóa hiệu suất: WebSocket có thể gửi dữ liệu nhỏ hơn và nhanh hơn so với HTTP, vì nó không cần phải truyền tải các header lớn cho mỗi yêu cầu.
Ứng dụng của WebSocket
- Trò chơi trực tuyến: Giao tiếp nhanh chóng và liền mạch giữa người chơi và máy chủ là rất quan trọng trong các trò chơi đa người.
- Ứng dụng nhắn tin: Các ứng dụng như WhatsApp Web hoặc Slack sử dụng WebSocket để gửi và nhận tin nhắn ngay lập tức.
- Dữ liệu tài chính: Ứng dụng giao dịch chứng khoán cần cập nhật giá cổ phiếu và thông tin thị trường trong thời gian thực.
- Ứng dụng theo dõi và giám sát: Các ứng dụng cần cập nhật thông tin từ cảm biến hoặc thiết bị IoT.
Cấu trúc tin nhắn WebSocket
Tin nhắn trong WebSocket được truyền dưới dạng khung (frame), bao gồm các loại khung như:
- Text Frame: Gửi dữ liệu văn bản (UTF-8).
- Binary Frame: Gửi dữ liệu nhị phân.
- Close Frame: Thông báo đóng kết nối.
- Ping/Pong Frame: Sử dụng để kiểm tra kết nối.
Demo website chat use websocket
Tôi đã tạo một ứng dụng chat đơn giản sử dụng WebSocket. Ứng dụng bao gồm 2 phần chính:
- Server (server.js):
- Sử dụng Node.js với thư viện
ws
để xử lý WebSocket. - Quản lý các kết nối client.
- Broadcast tin nhắn đến tất cả client đang kết nối.
- Phục vụ file HTML tĩnh
- Sử dụng Node.js với thư viện
- Client (index.html):
- Giao diện người dùng đơn giản với CSS
- Yêu cầu người dùng nhập username trước khi chat
- Kết nối WebSocket với server
- Hiển thị tin nhắn theo thời gian thực
- Tự động kết nối lại nếu mất kết nối
- Triển khai:
Phía server
Chạy các lệnh sau để tạo project node.js
mkdir websocket-chat-demo
cd websocket-chat-demo
npm init -y
npm install ws express
Tạo cấu trúc thư mục:
đây sẽ là code server
// server.js
const WebSocket = require("ws");
const http = require("http");
const express = require("express");
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
// Store connected clients
const clients = new Set();
wss.on("connection", (ws) => {
clients.add(ws);
// Send welcome message
ws.send(
JSON.stringify({
type: "info",
message: "Welcome to the chat!",
})
);
ws.on("message", (message) => {
try {
const data = JSON.parse(message);
// Broadcast message to all connected clients
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(
JSON.stringify({
type: "message",
username: data.username,
message: data.message,
timestamp: new Date().toISOString(),
})
);
}
});
} catch (error) {
console.error("Error parsing message:", error);
}
});
ws.on("close", () => {
clients.delete(ws);
});
});
app.use(express.static("public"));
server.listen(3000, () => {
console.log("Server is running on port 3000");
});
Giải thích code
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
app
: Tạo một ứng dụng Express.server
: Tạo một server HTTP sử dụng ứng dụng Express.wss
: Tạo một server WebSocket và liên kết nó với server HTTP.
wss.on("connection", (ws) => {})
- Đoạn code này để handle các connect từ client lên server websocket
clients.add(ws);
// Send welcome message
ws.send(
JSON.stringify({
type: "info",
message: "Welcome to the chat!",
})
);
clients
: Sử dụngSet
để lưu trữ tất cả các kết nối WebSocket hiện tại, đảm bảo mỗi client chỉ được lưu một lần.- Sau khi connect thì server sẽ gửi lại thông tin cho client nào lần đầu kết nối đến
ws.on("message", (message) => {
try {
const data = JSON.parse(message);
// Broadcast message to all connected clients
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(
JSON.stringify({
type: "message",
username: data.username,
message: data.message,
timestamp: new Date().toISOString(),
})
);
}
});
} catch (error) {
console.error("Error parsing message:", error);
}
});
- Đoạn code này mục đích đặt một sự kiện lắng nghe cho thông điệp đến từ client. Khi một thông điệp được nhận, nó sẽ cố gắng phân tích cú pháp thông điệp JSON.
- Nếu việc phân tích cú pháp thành công, nó sẽ gửi thông điệp đến tất cả các client kết nối bằng cách lặp qua tập hợp
clients
. Chỉ gửi đến những client có trạng thái mở (WebSocket.OPEN
). - Nếu có lỗi trong quá trình phân tích cú pháp thông điệp, lỗi sẽ được ghi vào console.
ws.on("close", () => { clients.delete(ws); });
- Khi một client ngắt kết nối, kết nối WebSocket sẽ bị xóa khỏi tập hợp
clients
.
Phía Client
ws = new WebSocket("ws://localhost:3000");
- Dòng mã này tạo một kết nối WebSocket đến server đang chạy trên
localhost
và cổng3000
.
ws.onmessage = (event) => {})
- Dòng này để hanlde các tin nhắn từ server trả về
- Trong demo này sau khi nhận data từ server thì client sẽ hiển thị lên giao diện.
ws.send(data)
- Dòng này để gửi data từ client lên server
Dưới đây là hình ảnh demo của chúng ta
Code mẫu tại đây
Cám ơn mọi người đã theo dõi bài viết, Happy coding!
Để lại một bình luận