Sau khi đọc xong thông số HTTP / 2 , tôi nghĩ rằng HTTP / 2 không phù hợp với websockets cho hầu hết các trường hợp sử dụng, nhưng có thể không phải tất cả.
PUSH_PROMISE
(thông thường được gọi là đẩy máy chủ) không phải là vấn đề ở đây. Đó chỉ là một tối ưu hóa hiệu suất.
Trường hợp sử dụng chính cho Websockets trong trình duyệt là cho phép truyền dữ liệu hai chiều. Vì vậy, tôi nghĩ rằng câu hỏi của OP trở thành liệu HTTP / 2 có thực hiện tốt hơn việc cho phép truyền phát hai chiều trong trình duyệt hay không và tôi nghĩ rằng có, nó có.
Trước hết, đó là bi-di. Chỉ cần đọc phần giới thiệu về phần stream :
"Luồng" là một chuỗi các khung độc lập, hai chiều được trao đổi giữa máy khách và máy chủ trong kết nối HTTP / 2. Luồng có một số đặc điểm quan trọng:
Một kết nối HTTP / 2 có thể chứa nhiều luồng mở đồng thời, với các khung xen kẽ điểm cuối từ nhiều luồng.
Các luồng có thể được thiết lập và sử dụng đơn phương hoặc được chia sẻ bởi máy khách hoặc máy chủ.
Các luồng có thể được đóng bởi một trong hai điểm cuối.
Các bài viết như thế này (được liên kết trong câu trả lời khác) là sai về khía cạnh này của HTTP / 2. Họ nói rằng đó không phải là thầu. Hãy nhìn xem, có một điều không thể xảy ra với HTTP / 2: Sau khi kết nối được mở, máy chủ không thể bắt đầu một luồng thông thường, chỉ một luồng đẩy. Nhưng một khi khách hàng mở một luồng bằng cách gửi yêu cầu, cả hai bên có thể gửi các khung DATA qua một ổ cắm liên tục bất cứ lúc nào - giá thầu đầy đủ.
Điều đó không khác nhiều so với websockets: máy khách phải bắt đầu yêu cầu nâng cấp websocket trước khi máy chủ cũng có thể gửi dữ liệu qua.
Sự khác biệt lớn nhất là, không giống như các websockets, HTTP / 2 định nghĩa ngữ nghĩa ghép kênh riêng của nó: cách các luồng nhận dạng định danh và cách các khung mang id của luồng chúng đang bật. HTTP / 2 cũng xác định ngữ nghĩa kiểm soát luồng để ưu tiên các luồng. Điều này rất quan trọng trong hầu hết các ứng dụng trong thế giới thực của hồ sơ dự thầu.
(Bài báo sai đó cũng nói rằng tiêu chuẩn Websocket có ghép kênh. Không, không. Thật sự không khó để tìm ra điều đó, chỉ cần mở Websocket RFC 6455 và nhấn-F, và gõ "ghép kênh".
Giao thức được dự định có thể mở rộng; các phiên bản trong tương lai có thể sẽ giới thiệu các khái niệm bổ sung như ghép kênh.
Bạn sẽ thấy rằng có bản mở rộng dự thảo 2013 cho ghép kênh Websocket. Nhưng tôi không biết trình duyệt nào, nếu có, hỗ trợ điều đó. Tôi sẽ không cố gắng xây dựng ứng dụng web SPA của mình ở mặt sau của tiện ích mở rộng đó, đặc biệt là với HTTP / 2 sắp tới, hỗ trợ có thể không bao giờ đến).
Ghép kênh chính xác là loại mà bạn thường phải tự làm bất cứ khi nào bạn mở một websocket cho thầu, giả sử, để cung cấp năng lượng cho một ứng dụng một trang cập nhật phản ứng. Tôi rất vui vì nó trong thông số HTTP / 2, được chăm sóc một lần và mãi mãi.
Nếu bạn muốn biết HTTP / 2 có thể làm gì, chỉ cần nhìn vào gRPC. gRPC được triển khai trên HTTP / 2. Nhìn cụ thể vào các tùy chọn phát song công một nửa và đầy đủ mà gRPC cung cấp. (Lưu ý rằng gRPC hiện không hoạt động trong trình duyệt, nhưng thực tế là do trình duyệt (1) không hiển thị khung HTTP / 2 cho javascript của máy khách và (2) thường không hỗ trợ Trailers, được sử dụng trong thông số gRPC.)
Trường hợp websockets vẫn có thể có một nơi? Cái lớn là máy chủ-> trình duyệt đẩy dữ liệu nhị phân. HTTP / 2 không cho phép máy chủ-> trình duyệt đẩy dữ liệu nhị phân, nhưng nó không bị lộ trong trình duyệt JS. Đối với các ứng dụng như đẩy khung hình âm thanh và video, đây là lý do để sử dụng websockets.
Chỉnh sửa: ngày 17 tháng 1 năm 2020
Theo thời gian, câu trả lời này đã dần dần tăng lên hàng đầu (điều này là tốt, bởi vì câu trả lời này ít nhiều đúng). Tuy nhiên, vẫn có những bình luận không thường xuyên nói rằng nó không đúng vì nhiều lý do, thường liên quan đến một số nhầm lẫn về PUSH_PROMISE
hoặc làm thế nào để thực sự sử dụng máy chủ hướng thông báo -> ứng dụng khách trong một ứng dụng trang. Và, có một trường hợp sử dụng cho websockets trong trình duyệt, đó là dữ liệu nhị phân do máy chủ đẩy. Đối với dữ liệu văn bản bao gồm JSON, không sử dụng websockets, hãy sử dụng SSE.
Tóm lại: Giao thức HTTP / 2 là bi-di đầy đủ. Tuy nhiên, các trình duyệt web hiện đại không hiển thị giao thức HTTP / 2 hướng khung thành JavaScript . Tuy nhiên, nếu bạn thực hiện nhiều yêu cầu cho cùng một nguồn gốc qua kết nối HTTP / 2, thì trong tất cả lưu lượng truy cập đó sẽ được ghép trên một kết nối (và đó là điều chúng tôi quan tâm!).
Vì vậy, nếu bạn cần xây dựng một ứng dụng trò chuyện thời gian thực, giả sử, nơi bạn cần phát các tin nhắn trò chuyện mới tới tất cả các khách hàng trong phòng trò chuyện có kết nối mở, bạn có thể (và có lẽ nên) làm điều này mà không cần websockets.
Bạn sẽ sử dụng Sự kiện gửi máy chủ để đẩy tin nhắn xuống và tìm nạp api để gửi yêu cầu lên. Sự kiện gửi máy chủ (SSE) là một API ít được biết đến nhưng được hỗ trợ tốt , hiển thị luồng máy chủ đến máy khách hướng đến thông báo. Mặc dù nó không giống với JavaScript của máy khách, nhưng trong trình duyệt của bạn (nếu nó hỗ trợ HTTP / 2) sẽ sử dụng lại một kết nối TCP duy nhất để ghép tất cả các thông báo đó. Không có mất hiệu quả và trên thực tế, đó là một lợi ích trên websockets. Cần nhiều luồng? Mở nhiều nguồn sự kiện! Họ sẽ được tự động ghép kênh cho bạn.
Bên cạnh việc tiết kiệm tài nguyên hiệu quả hơn và có độ trễ ban đầu ít hơn so với bắt tay websocket, Sự kiện gửi máy chủ có một đặc tính tốt là chúng tự động quay lại và hoạt động trên HTTP / 1.1. Nhưng khi bạn có kết nối HTTP / 2, chúng hoạt động rất tốt.
Đây là một bài viết hay với một ví dụ thực tế về việc hoàn thành SPA cập nhật phản ứng.