Zoom-in: WebSocket

Bạn gõ một tin nhắn trong khung chat, nhấn gửi, và đối phương lập tức nhìn thấy tin nhắn hiển thị mà không cần phải tải lại trang hay kéo-để-tải.
graph LR
C(["💻 Client 1"]) -->|"Tin nhắn gửi lên"| S(["🖥️ Server"])
S -->|"Đẩy thẳng xuống"| C2(["💻 Client 2"])
style C fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
style C2 fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
style S fill:#1a3a2a,stroke:#22c55e,color:#86efac
Phóng to dần vào đó.
Layer 1 — Polling: Nỗ lực truyền thông hai chiều thời kỳ đầu
Giao thức HTTP truyền thống được thiết kế theo mô hình request-response một chiều: client yêu cầu, server trả lời, rồi kết nối đóng lại. Server không thể tự ý chủ động gửi dữ liệu xuống client khi có tin nhắn mới.
Để tạo ra cảm giác "realtime", kỹ thuật sơ khai nhất là Polling (hỏi liên tục).
sequenceDiagram
participant C as Client
participant S as Server
C->>S: 1. Có tin nhắn mới không? (HTTP GET)
S-->>C: Không có.
Note over C: Chờ 2 giây...
C->>S: 2. Có tin nhắn mới không? (HTTP GET)
S-->>C: Không có.
Note over C: Chờ 2 giây...
C->>S: 3. Có tin nhắn mới không? (HTTP GET)
S-->>C: Có! "Chào bạn." (Data)
Client cứ mỗi 2 giây lại gửi một request HTTP mới để hỏi thăm. Kỹ thuật này gây lãng phí tài nguyên mạng khủng khiếp vì mỗi request HTTP đều phải mang theo các header cồng kềnh (cookie, user-agent), làm quá tải server và tạo ra độ trễ (latency) tối đa lên tới 2 giây.
Layer 2 — Handshake & Upgrade: Nâng cấp kết nối HTTP có sẵn
Thay vì tạo ra một cổng kết nối hoàn toàn mới (dễ bị các firewall chặn lại), WebSocket tái sử dụng cơ sở hạ tầng HTTP sẵn có qua một bước bắt tay đặc biệt gọi là Protocol Upgrade.
sequenceDiagram
participant C as Client
participant S as Server
C->>S: GET /chat HTTP/1.1 (Upgrade: websocket)
S-->>C: HTTP/1.1 101 Switching Protocols
Note over C,S: HTTP connection chuyển thành WebSocket connection (TCP persistent)
Client gửi một request HTTP GET thông thường lên server, nhưng đính kèm hai header quan trọng: Upgrade: websocket và Connection: Upgrade.
Nếu server hỗ trợ, nó sẽ trả về mã phản hồi 101 Switching Protocols. Từ giây phút này, kết nối HTTP ban đầu được "nâng cấp" thành một kết nối TCP persistent chạy giao thức WebSocket. Hai bên bắt đầu giao tiếp song song hai chiều (full-duplex).
Layer 3 — WebSocket Framing: Khung dữ liệu siêu nhỏ gọn
Sau khi hoàn tất nâng cấp kết nối, dữ liệu không còn truyền dưới dạng văn bản HTTP thô nữa. Thay vào đó, nó được chia nhỏ thành các khung dữ liệu cực kỳ tối giản gọi là Frames.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4b) |A| (7b) | (16/64b) |
|N|V|V|V| |S| | |
+-+-+-+-+-------+-+-------------+-------------------------------+
Một WebSocket frame chỉ tốn từ 2 đến 10 byte header để chứa thông tin điều khiển (loại dữ liệu là text hay binary, độ dài payload, mask key bảo mật). Phần còn lại hoàn toàn là dữ liệu thực tế (payload).
So với HTTP request tốn hàng trăm đến hàng ngàn byte cho đống header, WebSocket frame giúp tiết kiệm tối đa băng thông. Bên cạnh đó, WebSocket định nghĩa sẵn các frame điều khiển như Ping và Pong để hai đầu tự động kiểm tra xem đường truyền còn sống hay không mà không cần ứng dụng phải tự viết logic keep-alive.
Full picture
sequenceDiagram
participant C as Trình duyệt (Client)
participant S as WebSocket Server
Note over C,S: 1. Bắt tay nâng cấp (HTTP Handshake)
C->>S: GET /stream (Connection: Upgrade, Upgrade: websocket)
S-->>C: 101 Switching Protocols
Note over C,S: 2. Giao tiếp song hướng realtime (WebSocket Frames)
C->>S: Frame (Text: "Xin chào") - [Chỉ tốn 2 byte header]
S-->>C: Frame (Text: "Chào bạn")
Note over S: Có sự kiện mới trên Server!
S-->>C: Frame (Binary: Dữ liệu đồ thị mới)
Note over C,S: 3. Duy trì kết nối (Heartbeat)
S->>C: Frame (Ping)
C-->>S: Frame (Pong)
Note over C,S: 4. Đóng kết nối
C->>S: Frame (Close)
S-->>C: Frame (Close)
Note over C,S: Kết nối TCP chính thức đóng
Takeaway
WebSocket giải thoát các ứng dụng web khỏi giới hạn kéo dữ liệu một chiều của HTTP bằng cách chiếm quyền điều khiển (hijack) kết nối TCP sau bước bắt tay HTTP nâng cấp. Nhờ cắt bỏ các HTTP header cồng kềnh và thay bằng cấu trúc frame nhỏ gọn, WebSocket đem lại khả năng truyền tin hai chiều độ trễ cực thấp. Tuy nhiên, nó đòi hỏi server phải duy trì trạng thái kết nối (stateful), làm bài toán scale hệ thống trở nên phức tạp hơn nhiều so với HTTP stateless truyền thống.
Bài viết được hỗ trợ bởi Amy 🌸 - AI Assistant. Nội dung đã được kiểm duyệt bởi tác giả.
Related Posts
Zoom-in: CORS
Access-Control-Allow-Origin header is missing. Lỗi đỏ lòm quen thuộc trên console mỗi khi gọi API khác origin, nhưng tại sao nó lại tồn tại?
Zoom-in: TCP
Mọi HTTP request đều đi trên TCP — nhưng trước khi byte đầu tiên của dữ liệu đi qua, đã có 3 gói tin trao đổi mà không mang dữ liệu nào. TCP giải quyết vấn đề mà Internet không giải quyết được.
Zoom-in: Load Balancer
Một domain, hàng triệu request mỗi ngày. Load balancer không chỉ phân phối traffic — nó là điểm quyết định routing, health check, và session management cho toàn bộ hệ thống.