
WebSocket là giao thức cho phép trình duyệt và máy chủ trao đổi dữ liệu hai chiều liên tục trên cùng một kết nối. Nhờ đó, các ứng dụng thời gian thực như chat, bảng giá chứng khoán hay bản đồ điều khiển không còn phải liên tục hỏi máy chủ có gì mới bằng cách polling liên hồi.
Vì sao HTTP thường không đủ
HTTP vốn là giao thức một chiều: client gửi yêu cầu, server trả kết quả rồi kết thúc. Muốn nhận dữ liệu mới, client buộc phải gửi lại yêu cầu định kỳ. Cách này tốn nhiều request rỗng, độ trễ luôn bằng chu kỳ polling, và máy chủ phải giữ kết nối cho hàng nghìn client cùng lúc. Trước khi WebSocket ra đời, các kỹ thuật tạm thời như long-polling, Comet hay Flash Socket đều bị vướng chi phí bắt tay TCP và phần header HTTP lặp lại, rất tện cho các bản tin nhỏ.
WebSocket giải quyết đúng điểm đó. Nó không phải giao thức mới hoàn toàn tách rời, mà là một bước nâng cấp trên chính HTTP: client gửi yêu cầu HTTP thông thường kèm header Upgrade, server đáp lại mã 101 Switching Protocols, và từ đó kết nối chuyển sang trao đổi dữ liệu dạng khung nhị phân hai chiều.

Ba giai đoạn của một phiên WebSocket
- Bắt tay mở kết nối: client gửi GET kèm các header bắt buộc như Sec-WebSocket-Key, server trả về 101 cùng Sec-WebSocket-Accept tính từ khóa đó.
- Trao đổi khung tin: hai bên gửi các khung dữ liệu, khung điều khiển ping và pong, hoặc khung đóng.
- Bắt tay đóng: client gửi khung close, server phản hồi lại khung close rồi giải phóng tài nguyên.
Điểm đáng chú ý là sau bước bắt tay, chuỗi byte TCP thô không mang khái niệm tin nhắn. Do đó WebSocket định nghĩa một cấu trúc khung với các trường FIN, opcode, độ dài và khóa che. Bản mã hóa khung được sinh ra trên phía client bằng cách XOR dữ liệu với khóa 4 byte, còn server tuyệt đối không che khung gửi đi.

So sánh WebSocket với các lựa chọn khác
| Cơ chế | Hướng dữ liệu | Độ trễ | Độ phức tạp |
|---|---|---|---|
| Poling | Client hỏi, server trả | Không xác định | Thấp |
| Server-Sent Events | Một chiều từ server | Thấp | Thấp |
| WebSocket | Hai chiều toàn thời gian | Thấp | Trung bình |
| gRPC streaming | Hai chiều, nhị phân | Thấp | Cao |
Server-Sent Events là lựa chọn nhẹ hơn khi ứng dụng chỉ cần server đẩy dữ liệu xuống, vì nó chạy trên HTTP thuần và tự động kết nối lại. Ngược lại, khi cả hai đầu đều cần gửi dữ liệu liên tục, WebSocket vẫn là lựa chọn mặc định phổ biến vì hỗ trợ nhị phân, độ trễ thấp và một kết nối duy nhất cho mọi chiều dữ liệu.

Làm việc thực tế và bảo mật
Hầu hết trình duyệt lớn đều hỗ trợ sẵn WebSocket. Ở phía máy chủ, Nginx đã hỗ trợ WebSocket từ bản 1.3.13 và thường được dùng làm reverse proxy, trong khi Apache hỗ trợ từ 2.4.5, IIS từ phiên bản 8 và lighttpd từ 1.4.46. Trong các ứng dụng Node.js hay Python, thư viện phía server chủ yếu lo phần đóng khung và giữ vòng đời kết nối.
Về bảo mật, một chi tiết dễ bị bỏ qua: yêu cầu WebSocket không chịu ràng buộc chính sách cùng nguồn giống các request HTTP thường. Vì vậy server bắt buộc phải tự kiểm tra header Origin trước khi chấp nhận bắt tay, nếu không sẽ mở đường cho tấn công cross-site WebSocket hijacking. Ngoài ra, tiền tố wss dùng cổng 443 với lớp bảo mật TLS đang dần trở thành mặc định, vì nhiều mạng doanh nghiệp chặn các cổng không tiêu chuẩn.
Khi nào nên chọn WebSocket
WebSocket không phải lựa chọn mặc định cho mọi bài toán thời gian thực. Nếu dữ liệu chỉ chạy một chiều từ server xuống người dùng và tần suất thấp, sử dụng long-polling thường đơn giản hơn, dễ cache hơn và không giữ kết nối mở liên tục trên server. Ngược lại, khi hệ thống cần hai bên cùng gửi lệnh liên tục, hoặc cần truyền khối dữ liệu nhị phân như khung hình video, cửa sổ terminal hay trạng thái trò chơi, WebSocket gần như không có đối thủ trực tiếp.
Một điểm cần cân nhắc là chi phí phía server. Mỗi kết nối WebSocket là một kết nối TCP thật, nên tốn một file descriptor và bộ nhớ cho mỗi client đang mở. Với ứng dụng có hàng trăm nghìn người dùng đồng thời, cần cân nhắc dùng thư viện hỗ trợ WebSocket cho ứng dụng như Node.js với thư viện ws, Go với gorilla/websocket hay Python với websockets, kèm cơ chế cân bằng tải và giới hạn số kết nối mỗi IP. Bạn có thể đọc thêm bài Nginx là gì: Reverse proxy và load balancer phổ biến nhất để biết cách cấu hình proxy đúng cho WebSocket.
Kết luận
WebSocket đã trở thành lớp giao tiếc mặc định cho mọi tính năng thời gian thực trên web. Cơ chế bắt tay dựa trên HTTP giúp nó dễ triển khai sau mọi reverse proxy hiện có, còn cấu trúc khung nhị phân giúp tiết kiệm băng thông so với việc mở nhiều request HTTP. Nếu bạn đang xây tính năng chat, dashboard giá hay cộng tác trực tiếp, đây gần như là lựa chọn mặc định hợp lý. Bạn cũng có thể đọc thêm bài giải thích gRPC là gì để so sánh với hướng RPC dựa trên HTTP/2, và tài liệu WebSocket chính thức của MDN để có chi tiết về API phía trình duyệt.
