WebSocket là gì: Truyền dữ liệu hai chiều thời gian thực

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.

Sơ đồ WebSocket: máy chủ và trình duyệt trao đổi dữ liệu hai chiều qua một kết nối liên tục

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.

Sơ đồ cấu trúc khung tin WebSocket với các trường FIN, opcode, độ dài và khóa che

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.

Sơ đồ Server-Sent Events: luồng dữ liệu một chiều từ máy chủ xuống trình duyệt

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.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Zero Trust là gì: Kiến trúc bảo mật không tin tưởng mặc định

Zero Trust (ZT) không chỉ là một cụm từ quảng bá, mà là một kiến trúc bảo mật hoàn toàn thay đổi cách tư duy về phòng vệ mạng doanh…

Xem thêm

Li-Fi là gì: Truyền dữ liệu bằng ánh sáng thay cho Wi-Fi

Li-Fi là gì? Li-Fi (viết tắt của Light Fidelity) là công nghệ truyền dữ liệu không dây bằng ánh sáng nhìn thấy, thay vì bằng sóng vô tuyến như Wi-Fi….

Xem thêm

eBPF là gì: Công nghệ lập trình trong nhân Linux hiện đại

eBPF là gì? eBPF (extended Berkeley Packet Filter) là công nghệ cho phép chạy các chương trình nhỏ gọn, an toàn ngay bên trong nhân Linux mà không cần sửa…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất