Giới thiệu
WebSocket là một giao thức cho phép kết nối song công, kết nối bền vững giữa máy khách và máy chủ qua một socket TCP duy nhất. Khác với HTTP thuần túy nơi client phải gửi yêu cầu và server trả về, kết nối WebSocket duy trì mở và cả hai bên có thể gửi tin nhắn bất cứ lúc nào. Điều này làm cho nó hoàn hảo cho ứng dụng chat, bảng điều khiển thời gian thực, trò chơi nhiều người chơi và bất kỳ tính năng nào cần cập nhật thời gian thực.
Trong bài học này bạn sẽ xây dựng thiết lập WebSocket nhỏ nhất có thể: một máy chủ bằng Node.js sử dụng thư viện `ws` phổ biến, và một client trình duyệt kết nối với nó và trao đổi vài tin nhắn. Không dùng framework, không cơ sở dữ liệu — chỉ giao thức thô để bạn hiểu những gì đang diễn ra từ bên trong.
Thiết lập Dự án
Tạo một thư mục mới cho dự án và khởi tạo nó. Bạn cần cài đặt Node.js (phiên bản 18 hoặc cao hơn là được).
Gói `ws` là một triển khai WebSocket nhanh, được sử dụng rộng rãi cho Node.js. Sau khi chạy `npm install`, bạn sẽ có một thư mục `node_modules` và một `package.json` liệt kê `ws` là một phụ thuộc.
Viết máy chủ
Tạo một file có tên `server.js`. Máy chủ thực hiện ba việc: nhập thư viện, tạo một máy chủ WebSocket được gán vào một cổng, và xác định điều gì sẽ xảy ra khi có kết nối và khi nhận tin nhắn.
Sự kiện `connection` được kích hoạt mỗi lần có một khách hàng kết nối. Callback nhận một đối tượng `ws` đại diện cho socket của từng khách hàng cụ thể. Bên trong callback bạn gán một listener `message`. Khi một tin nhắn đến, `data` mặc định là một Buffer, vì vậy `toString()` chuyển nó thành văn bản thuần túy. Máy chủ sau đó gửi lại tin nhắn được gán tiền tố `Server echo:`.
Chạy máy chủ với `node server.js`. Bạn sẽ thấy dòng nhật ký "listening" và không có gì khác cho đến khi có một client kết nối.
Viết Browser Client
Tạo một file có tên `index.html`. Trình duyệt có thể mở kết nối WebSocket bằng đối tượng toàn cục tích hợp `WebSocket` — không cần thư viện ở phía client.
Sự kiện `open` kích hoạt khi tiến trình bắt tay hoàn tất. Sau đó, `ws.send('text')` gửi một chuỗi đến server. Phản hồi được server gợi lại sẽ nhận về dưới dạng sự kiện `message` mà `event.data` là chuỗi mà server đã gửi.
Kiểm thử End-to-End
Chạy máy chủ với `node server.js`. Sau đó mở `index.html` trong trình duyệt của bạn (có thể nhấp đúp vào file, hoặc dùng công cụ như `npx serve`). Trong terminal bạn sẽ thấy "A client connected" ngay lúc trang được tải. Gõ gì đó vào hộp input và nhấp Gửi. Nhật ký trình duyệt sẽ hiển thị tin nhắn của bạn được tiền tố bởi `Server echo:`, và terminal sẽ ghi nhận mỗi thông điệp mà server nhận.
Những sai lầm phổ biến
Quên gọi `data.toString()` ở phía server sẽ trả về một đối tượng Buffer thô thay vì chuỗi có thể đọc được mà client gửi. Quên tiền tố giao thức `ws://` trong URL trình duyệt sẽ gây ra lỗi cú pháp vì constructor `WebSocket` đòi URL đầy đủ bao gồm scheme. Nếu server chưa chạy, sự kiện `open` của trình duyệt sẽ không bao giờ kích hoạt và bạn sẽ thấy không có log — luôn kiểm tra terminal trước khi có điều gì đó xảy ra.
Tóm tắt
Bây giờ bạn có một máy chủ echo WebSocket hoạt động và một client trình duyệt. Server dùng `ws` để lắng nghe trên cport 8080, chấp nhận kết nối và lặp lại bất kỳ tin nhắn nào nhận được. Client mở kết nối với `new WebSocket('ws://localhost:8080')` và dùng `send` cùng các sự kiện `message` để giao tiếp. Mô hình này — một máy chủ, nhiều client kết nối, tin nhắn hai chiều — là nền tảng mà mọi tính năng thời gian thực đều dựa vào.
Bài kiểm tra cuối bài
Ôn lại kiến thức, thử sức và nhận góp ý cho bài làm.