Cơ sở lý thuyết của giao thức WebSocket
Giao thức WebSocket được xây dựng trên nền tảng các kết nối mạng TCP/IP, đặc trưng bởi địa chỉ IP (hoặc tên miền thay thế) và số cổng. Giao thức HTTP/HTTPS, mà chúng ta đã thực hành trong chương về chức năng mạng, hoạt động dựa trên nguyên tắc tương tự. Ở đó, các số cổng tiêu chuẩn là 80 (cho kết nối không an toàn) và 443 (cho kết nối an toàn). Không có số cổng chuyên dụng cho WebSocket, vì vậy các nhà cung cấp dịch vụ web có thể chọn bất kỳ số nào còn trống. Tất cả các ví dụ của chúng ta sẽ sử dụng cổng 9000.
Khi chỉ định URL dưới dạng tiền tố giao thức WebSocket, chúng ta sử dụng ws
(cho kết nối không an toàn) và wss
(cho kết nối an toàn).
Định dạng WebSocket hiệu quả hơn về mặt truyền dữ liệu so với HTTP vì nó sử dụng ít dữ liệu điều khiển hơn nhiều.
Việc thiết lập kết nối ban đầu cho dịch vụ WebSocket hoàn toàn lặp lại yêu cầu trang web HTTP/HTTPS: bạn cần gửi một yêu cầu GET với các tiêu đề được chuẩn bị đặc biệt. Đặc điểm của các tiêu đề này là sự hiện diện của các dòng:
Connection: Upgrade
Upgrade: websocket
2
cũng như một số dòng bổ sung thông báo phiên bản của giao thức WebSocket và các chuỗi ngẫu nhiên đặc biệt. Các khóa tham gia vào quy trình "bắt tay" giữa máy khách và máy chủ.
Sec-WebSocket-Key: ...
Sec-WebSocket-Version: 13
2
Trong thực tế, "bắt tay" ngụ ý rằng máy chủ kiểm tra tính khả dụng của các tùy chọn mà máy khách yêu cầu, và trong phản hồi với các tiêu đề HTTP tiêu chuẩn, xác nhận việc chuyển sang chế độ WebSocket hoặc từ chối nó. Lý do đơn giản nhất để từ chối có thể là nếu bạn đang cố gắng kết nối qua WebSocket đến một máy chủ web đơn giản nơi máy chủ WebSocket không được cung cấp hoặc phiên bản yêu cầu không được hỗ trợ.
Phiên bản hiện tại của giao thức WebSocket được biết đến dưới tên mã Hybi và số 13. Một phiên bản trước đó và đơn giản hơn gọi là Hixie có thể hữu ích cho khả năng tương thích ngược. Trong phần tiếp theo, chúng ta sẽ chỉ sử dụng Hybi, mặc dù triển khai Hixie cũng được bao gồm.
Kết nối thành công được biểu thị bằng các tiêu đề HTTP sau trong phản hồi của máy chủ:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: ...
2
3
4
Trường Sec-WebSocket-Accept
ở đây được máy chủ tính toán và điền dựa trên Sec-WebSocket-Key
để xác nhận sự tuân thủ giao thức. Tất cả điều này được quy định bởi thông số kỹ thuật RFC6455 và sẽ được hỗ trợ trong các chương trình MQL của chúng ta.
Để minh họa rõ ràng, quy trình được hiển thị trong hình ảnh sau:
Tương tác giữa máy khách và máy chủ qua giao thức WebSocket
Sau khi thiết lập kết nối WebSocket, máy khách và máy chủ có thể trao đổi thông tin được đóng gói thành các khối đặc biệt: khung và thông điệp. Một thông điệp có thể bao gồm một hoặc nhiều khung. Kích thước khung, theo thông số kỹ thuật, bị giới hạn ở con số khổng lồ 2^63 byte (9223372036854775807 ~ 9.22 exabyte!), nhưng các triển khai cụ thể đương nhiên có thể có giới hạn thực tế hơn vì giới hạn lý thuyết này không thực tế cho việc gửi trong một gói.
Bất kỳ lúc nào, máy khách hoặc máy chủ có thể chấm dứt kết nối, sau khi đã "lịch sự nói lời tạm biệt" trước đó (xem bên dưới) hoặc chỉ đơn giản bằng cách đóng socket mạng.
Các khung có thể thuộc nhiều loại khác nhau như được chỉ định trong tiêu đề của chúng (dài từ 4 đến 16 byte) xuất hiện ở đầu mỗi khung. Để tham khảo, hãy liệt kê các mã hoạt động (có trong byte đầu tiên của tiêu đề) và mục đích của các khung thuộc các loại khác nhau.
- 0 — khung tiếp tục (kế thừa các thuộc tính của khung trước đó);
- 1 — khung chứa thông tin văn bản;
- 2 — khung chứa thông tin nhị phân;
- 8 — khung yêu cầu đóng và xác nhận đóng kết nối (được gửi để "tạm biệt lịch sự");
- 9 — khung ping, có thể được gửi định kỳ bởi một trong hai bên để đảm bảo kết nối vẫn được duy trì vật lý;
- 10 — khung pong, được gửi để đáp lại khung ping.
Khung cuối cùng trong một thông điệp được đánh dấu bằng một bit đặc biệt trong tiêu đề. Tất nhiên, khi một thông điệp chỉ gồm một khung, nó cũng là khung cuối cùng. Độ dài của tải trọng cũng được truyền trong tiêu đề.