HTTP / 2 có làm cho websockets bị lỗi thời không?


268

Tôi đang tìm hiểu về giao thức HTTP / 2. Đó là một giao thức nhị phân với các khung tin nhắn nhỏ. Nó cho phép ghép kênh theo kết nối TCP. Về mặt khái niệm nó có vẻ rất giống với WebSockets.

Có kế hoạch để lỗi thời websockets và thay thế chúng bằng một số loại yêu cầu HTTP / 2 không tiêu đề và tin nhắn đẩy do máy chủ khởi tạo không? Hoặc WebSockets sẽ bổ sung HTTP / 2?


Tôi nghĩ rằng câu trả lời được chấp nhận là chính xác, websockets vẫn là giải pháp ưa thích để các ứng dụng web liên lạc với máy chủ hai chiều bao gồm các tin nhắn đẩy máy chủ. HTTP được sử dụng cho nhiều hơn chỉ các trình duyệt và khi cả máy khách và máy chủ có thể sử dụng API cấp thấp, chúng không cần websockets. Tuy nhiên, hầu hết mọi người sử dụng HTTP cho các ứng dụng web và chủ yếu quan tâm đến các API tiếp xúc với JavaScript. Nếu người điều hành nghĩ rằng câu trả lời được chấp nhận sẽ khác, thì tôi không phản đối vì câu hỏi này rõ ràng tạo ra rất nhiều quan điểm và ý kiến ​​của tôi có thể sai.
vbezhenar

Câu trả lời:


162

Từ những gì tôi hiểu HTTP / 2 không phải là sự thay thế cho websocket mà nhằm mục đích chuẩn hóa giao thức SPDY.

Trong HTTP / 2, máy chủ đẩy được sử dụng phía sau hiện trường để cải thiện việc tải tài nguyên của máy khách từ trình duyệt. Là một nhà phát triển, bạn không thực sự quan tâm đến nó trong quá trình phát triển của mình. Tuy nhiên, với Websocket, nhà phát triển được phép sử dụng API có khả năng tiêu thụ và đẩy tin nhắn với kết nối song công hoàn toàn độc đáo.

Đây không phải là những điều tương tự, và họ nên bổ sung cho nhau.


3
Cảm ơn bạn Guillaume cho câu trả lời của bạn. Tuy nhiên tôi tự hỏi nếu bạn (hoặc ai đó) có thể thêm một số tham chiếu từ đặc tả HTTP / 2. Những gì tôi đã đọc từ blog và vv - với HTTP / 2 có một giao tiếp hai chiều thực sự?
Martin Meeser

3
Không chắc chắn thông số HTTP / 2 là nơi thích hợp để cung cấp chi tiết về nguồn gốc của HTTP / 2 và nó khác với websocket như thế nào. Tuy nhiên, bạn có thể dễ dàng thấy rằng với HTTP / 2, chúng tôi đang sử dụng giao tiếp hai chiều: goo.gl/IJVxWS (trang 6 và 13)
Guillaume D.

27
HTTP / 2 thực sự là hai chiều nhưng không đối xứng, có nghĩa là chỉ khách hàng mới có thể gửi yêu cầu thích hợp và máy chủ có thể gửi phản hồi và yêu cầu hứa hẹn (đẩy). Điều này làm cho các websockets khác nhau theo nghĩa là cả hai bên đều "bằng nhau" hơn về những gì họ được phép gửi / nhận.
George Antoniadis

3
Có một podcast tuyệt vời trên Radio Engineering Engineering Radio của IEEE về nguồn gốc của HTTP2. Tôi nghĩ đây là nó: se-radio.net/2015/07/epiT-232-mark-nottingham-on-http2
Max Murphy

2
Câu trả lời tương tự với lý do đầy đủ có thể được tìm thấy trong bài viết InfoQ này tại đây: infoq.com/articles/websocket-and-http2-coexist
mantrid

151

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, đó 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_PROMISEhoặ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.


21
Câu trả lời này một phần không đồng ý với những câu hỏi khác, bao gồm câu trả lời được chấp nhận và đó cũng là câu trả lời tốt nhất vì nó dựa trên các nguồn trực tiếp.
sudo

7
Tôi hoàn toàn đồng ý với câu trả lời này và bình luận. HTTP / 2 được truyền trực tiếp hai chiều.
Martin Meeser

3
Thực tế câu trả lời đúng, anh chàng bận tâm kiểm tra các nguồn và ứng dụng trong thế giới thực (grpc)
Vladimir Akopyan

1
Trong websockets, máy chủ không thể bắt đầu đẩy các byte tùy ý cho đến khi máy khách bắt đầu yêu cầu nâng cấp websocket, nhưng sau đó nó có thể đẩy bất cứ lúc nào. Trong HTTP / 2, máy chủ không thể bắt đầu đẩy byte cho đến khi máy khách khởi tạo kết nối dữ liệu, nhưng sau đó nó có thể đẩy byte bất cứ lúc nào. Sự khác biệt chức năng là gì? Như tôi đã chỉ ra, khả năng PUSH_PROMISE là cá trích đỏ. Nó không phải là lý do tại sao HTTP / 2 là sự thay thế cho các ổ cắm web. Nó chỉ là một tối ưu hóa hiệu suất nhỏ sang một bên. Nó không liên quan gì đến trái tim của HTTP / 2, đó là tính năng phát trực tuyến.
masonk

1
Câu trả lời này đơn giản là sai. Nó nhầm lẫn rất nhiều khía cạnh mà nó dễ gây nhầm lẫn. Tuy nhiên, mấu chốt của vấn đề là các luồng HTTP / 2 "có giá trị" được điều khiển theo yêu cầu (và bị giới hạn về số lượng), trong khi giao thức WebSockets là giao thức thầu dựa trên thông điệp thực sự (nó không dựa trên phản hồi yêu cầu, ngoại trừ giai đoạn bắt tay). Đây là một sự khác biệt lớn không thể được bắc cầu chỉ bằng cách đọc sai đặc tả (như @masonk vô tình dường như đã làm).
Bí ẩn

65

Tôi nói Nay ( Websockets không lỗi thời ).

Vấn đề đầu tiên và thường bị bỏ qua nhất là việc đẩy HTTP / 2 không thể thực thi được và có thể bị bỏ qua bởi proxy, bộ định tuyến, các trung gian khác hoặc thậm chí trình duyệt.

tức là (từ bản nháp HTTP2):

Một trung gian có thể nhận được các lần đẩy từ máy chủ và chọn không chuyển tiếp chúng cho khách hàng . Nói cách khác, làm thế nào để sử dụng thông tin đẩy là tùy thuộc vào trung gian đó. Tương tự, trung gian có thể chọn thực hiện các lần đẩy bổ sung cho máy khách mà không có bất kỳ hành động nào được thực hiện bởi máy chủ.

Do đó, HTTP / 2 Push không thể thay thế WebSockets.

Ngoài ra, các kết nối HTTP / 2 sẽ đóng lại sau một thời gian.

Đúng là tiêu chuẩn quy định rằng:

Kết nối HTTP / 2 là liên tục. Để có hiệu suất tốt nhất, khách hàng sẽ không đóng các kết nối cho đến khi xác định rằng không cần liên lạc với máy chủ nữa (ví dụ: khi người dùng điều hướng khỏi một trang web cụ thể) hoặc cho đến khi máy chủ đóng kết nối.

Nhưng...

Máy chủ được khuyến khích duy trì các kết nối mở càng lâu càng tốt nhưng được phép chấm dứt các kết nối nhàn rỗi nếu cần thiết. Khi một trong hai điểm cuối chọn đóng kết nối TCP lớp vận chuyển, điểm cuối kết thúc trước tiên NÊN gửi khung GOAWAY (Mục 6.8) để cả hai điểm cuối có thể xác định một cách đáng tin cậy liệu các khung đã gửi trước đó đã được xử lý và hoàn thành một cách duyên dáng hay chấm dứt bất kỳ nhiệm vụ cần thiết nào còn lại.

Ngay cả khi cùng một kết nối cho phép đẩy nội dung trong khi nó đang mở và ngay cả khi HTTP / 2 giải quyết được một số vấn đề về hiệu suất được giới thiệu bởi các kết nối HTTP / 1.1 thì 'giữ nguyên' ... các kết nối HTTP / 2 không được mở vô thời hạn .

Trang web cũng không thể khởi tạo lại kết nối HTTP / 2 sau khi đóng (trừ khi chúng tôi quay lại kéo dài), đó là).

EDIT (2017, hai năm sau)

Việc triển khai HTTP / 2 cho thấy nhiều tab / cửa sổ trình duyệt chia sẻ một kết nối HTTP / 2, nghĩa là pushsẽ không bao giờ biết nó thuộc về tab / cửa sổ nào, loại bỏ việc sử dụng pushthay thế cho Websockets.

EDIT (2020)

Tôi không chắc tại sao mọi người bắt đầu hạ thấp câu trả lời. Nếu bất cứ điều gì, những năm kể từ khi câu trả lời ban đầu được đăng đã chứng minh rằng HTTP / 2 không thể thay thế WebSockets và không được thiết kế để làm như vậy.

Cấp, HTTP / 2 có thể được sử dụng để hầm kết nối WebSocket, nhưng những kết nối đường hầm vẫn sẽ yêu cầu giao thức WebSocket và họ sẽ ảnh hưởng đến cách thức HTTP / 2 cư xử container.


4
Ổ cắm WS sẽ không mở mãi mãi. Sự khác biệt là dòng; HTTP / 2 cung cấp cho bạn nhiều luồng luồng, điều đó có nghĩa là điều khiển luồng trên máy chủ rất khác nhau và thường không khóa. WS (như một giao thức) phải được xử lý trong nước không được kiểm soát. Kiểm soát dòng chảy được thực hiện cao hơn lên ngăn xếp. Về bảo mật và tính toàn vẹn của máy chủ, HTTP / 2 tốt hơn nhiều so với WS.
trái phiếu

3
@bond, tôi đồng ý rằng HTTP / 2 có nhiều lợi thế như một lớp vận chuyển (chia sẻ một kết nối duy nhất trên nhiều tab trình duyệt chỉ là một ví dụ). Tuy nhiên, nó không được thiết kế như một lớp giao tiếp . Đây là một câu hỏi chức năng. Cả hai giao thức trả lời các nhu cầu khác nhau. tức là thực hiện một sshthiết bị đầu cuối trên trình duyệt rất dễ dàng khi sử dụng Websockets. Nó sẽ là một vấn đề đau đầu trên HTTP / 2, đặc biệt là nếu nhiều hơn một tab được mở. Ngoài ra, nếu trình duyệt (hoặc một trong các proxy HTTP / 2) đóng kết nối thì sao? Khách hàng có thể cho rằng không có dữ liệu mới có sẵn? chúng tôi trở lại bỏ phiếu.
Bí ẩn

1
Trình duyệt có thể dễ dàng đóng kết nối WS của bạn. Đó là cuộc sống với bất kỳ loại mạng. Thành thật mà nói, việc ghép kênh trong HTTP / 2 là quá mức cần thiết. Giao thức thực sự không cần nó. Với việc mở nhiều luồng, bạn bắt đầu gặp vấn đề với bộ đệm TCP giới hạn thông lượng. Tôi đồng ý với bạn rằng WS tốt hơn những gì nó làm hơn HTTP / 2. Về cơ bản, WS là thứ cần nhiều kiểm soát mức cao hơn để ngăn người dùng làm điều xấu.
trái phiếu

2
Trích lời chú Ben (Người nhện): "Hãy nhớ rằng, với sức mạnh to lớn sẽ có trách nhiệm lớn". Vâng, @bond, bạn rất đúng. Websockets, là một giao thức rất "thô", đòi hỏi thiết kế máy chủ có trách nhiệm hơn. Và vâng, WS có thể được đóng dễ dàng như HTTP / 2, nhưng WS hỗ trợ onclosegọi lại, do đó không cần bỏ phiếu. Đối với ghép kênh, tôi nghĩ rằng đó là một điều cần thiết chứ không phải là một sự lựa chọn. keep-alivethất bại và cách duy nhất để tránh cú đánh hiệu năng "đầu tiên" là mạo hiểm ghép kênh. Thời gian sẽ trả lời :)
Myst

1
Từ quan điểm thiết kế máy chủ, việc ghép kênh ra bên ngoài là một vấn đề phức tạp và tốn kém. Nó đòi hỏi các cơ chế IO để thăm dò ý kiến ​​nội bộ đắt đỏ như địa ngục. Trừ khi bạn đang truyền phát các tài liệu lớn, bộ ghép kênh sẽ không hoạt động bởi vì yêu cầu có thể sẽ được phản hồi và được đệm hoàn toàn bên trong trước khi thứ hai thậm chí trở nên khả dụng và bộ ghép kênh không chạy được. RTMP có ghép kênh ngoài nhưng chỉ có máy chủ của Adobe làm điều đó. Thật đáng ngạc nhiên khi HTTP / 2 gần với RTMP.
trái phiếu

39

Câu trả lời là không. Mục tiêu giữa hai người rất khác nhau. Thậm chí còn có RFC cho WebSocket qua HTTP / 2 cho phép bạn thực hiện nhiều kết nối WebSocket qua một ống TCP / 2 TCP duy nhất.

WS trên HTTP / 2 sẽ là một trò chơi bảo tồn tài nguyên bằng cách giảm thời gian mở các kết nối mới và cho phép nhiều kênh liên lạc hơn mà không phải trả thêm chi phí cho nhiều ổ cắm, IRQ mềm và bộ đệm.

https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01


Thật ngạc nhiên! Có ví dụ công khai nào về máy khách Javascript đã triển khai việc này không? Tôi không thể tìm thấy bất kỳ ví dụ. Tôi cần làm gì? Đây có phải là một nguồn tài nguyên tốt? undertow.io/blog/2015/04/27/An-in-depth-overview-of-HTTP2.html
RaisinBranCrunch

Có ai biết một nguồn của các tuyên bố trên về 1) tìm độ dài của tiêu đề, 2) thấp hơn các tên trường không?
Pim Heijden

@PimHeijden phát hiện độ dài tiêu đề trong HTTP / 1.x yêu cầu lặp qua tất cả các byte tìm kiếm điểm đánh dấu kết thúc 4 byte. Thứ đó rất mắc. Tính không phân biệt chữ hoa chữ thường của trường cũng có nghĩa là bất kỳ trường khớp nào cũng phải được thực hiện cho cả phiên bản chữ hoa và chữ thường của các ký tự. Điều này đòi hỏi kiến ​​thức của toàn bộ bảng mã cho chữ hoa và chữ thường để kiểm tra. Trong 2.x bạn có thể giả sử họ là chữ thường.
trái phiếu

@RaisinBranCrunch Bạn không thể kiểm soát bất kỳ điều này từ Javascript. Trình duyệt làm mọi thứ cho bạn.
trái phiếu

@bond Tôi hiện đang sử dụng HTTP / 2 với Nginx và proxy_pass để gửi kết nối websocket đến máy chủ ổ cắm, nhưng khi tôi có một người dùng mở nhiều tab trong trang web, máy chủ ổ cắm coi nó là nhiều kết nối. Tôi sẽ giả sử rằng nếu HTTP / 2 là kết nối ghép kênh trên một ống TCP, thì máy chủ sẽ coi nó là một kết nối. Điều này có sai không? Có cách nào để xác minh rằng máy chủ không tạo thêm kết nối không cần thiết?
RaisinBranCrunch

23

Vâng, để trích dẫn từ bài viết InfoQ này:

Chà, câu trả lời rõ ràng là không, vì một lý do đơn giản: Như chúng ta đã thấy ở trên, HTTP / 2 giới thiệu Server Push cho phép máy chủ chủ động gửi tài nguyên vào bộ đệm của máy khách. Tuy nhiên, nó không cho phép đẩy dữ liệu xuống ứng dụng khách. Các lần đẩy máy chủ chỉ được trình duyệt xử lý và không bật lên mã ứng dụng, nghĩa là không có API cho ứng dụng để nhận thông báo cho các sự kiện đó.

Và vì vậy, HTTP2 thực sự là một cái gì đó giữa trình duyệt và máy chủ của bạn, trong khi Websockets thực sự phơi bày các API có thể được sử dụng bởi cả máy khách (javascript, nếu nó chạy trên trình duyệt) và mã ứng dụng (chạy trên máy chủ) để truyền dữ liệu thời gian thực.


5

Trao đổi tin nhắn và truyền phát đơn giản (không phải âm thanh, truyền phát video) có thể được thực hiện thông qua cả ghép kênh http / 2 và WebSockets. Vì vậy, có một số chồng chéo, nhưng WebSockets có giao thức được thiết lập tốt, rất nhiều khung / API và ít tiêu đề hơn. Đây là bài viết tốt đẹp về chủ đề này .


2

Sẽ có triển khai WebSocket trong HTTP / 2. https://tools.ietf.org/html/rfc8441


Không có sẽ không ... kết nối WebSocket sẽ được tạo đường hầm thông qua HTTP / 2, nhưng HTTP / 2 sẽ không thay thế các giao thức, và cũng không nó sẽ trở nên lỗi thời.
Bí ẩn

@Myst Tôi có nói vậy không?
Dzintars

2
Không, bạn đã không nói rằng, tôi đã làm. Bạn đã viết rằng sẽ có một triển khai WebSocket trong HTTP / 2, mà IMHO dường như quá ngắn và hơi sai lệch do các chi tiết quan trọng bị bỏ qua.
Bí ẩn

2

Hiện tại, tháng 4 năm 2020, HTTP / 2 không khiến WebSockets trở nên lỗi thời. Ưu điểm lớn nhất của WebSockets so với HTTP2 là

HTTP/2 works only on Browser Level not Application Level

Có nghĩa là HTTP / 2 không cung cấp bất kỳ API JS nào như WebSockets để cho phép giao tiếp và chuyển một số loại JSON hoặc dữ liệu khác đến máy chủ trực tiếp từ Ứng dụng (ví dụ: Trang web). Vì vậy, theo như tôi tin, HTTP / 2 sẽ chỉ khiến WebSockets trở nên lỗi thời nếu nó bắt đầu cung cấp API như WebSockets để nói chuyện với máy chủ. Cho đến khi nó chỉ là phiên bản cập nhật và nhanh hơn của HTTP 1.1.


2

Cho đến hôm nay, không.

HTTP / 2, so với HTTP, cho phép bạn duy trì kết nối với máy chủ. Từ đó, bạn có thể có nhiều luồng dữ liệu cùng một lúc. Mục đích là bạn có thể đẩy nhiều thứ cùng một lúc ngay cả khi khách hàng không yêu cầu. Ví dụ: khi trình duyệt yêu cầu index.html, máy chủ có thể muốn đẩy index.cssindex.js. Trình duyệt không yêu cầu, nhưng máy chủ có thể cung cấp mà không cần hỏi vì có thể cho rằng bạn sẽ muốn trong vài giây.

Đây là nhanh hơn so với HTTP / 1 thay thế nhận index.html, phân tích nó, khám phá nó cần index.jsindex.csssau đó xây dựng 2 yêu cầu khác đối với những tập tin. HTTP / 2 cho phép máy chủ đẩy dữ liệu mà khách hàng thậm chí không yêu cầu.

Trong bối cảnh đó, nó tương tự như WebSocket, nhưng không thực sự theo thiết kế. WebSocket được cho là cho phép giao tiếp hai chiều tương tự như kết nối TCP hoặc kết nối nối tiếp. Đó là một ổ cắm nơi cả hai giao tiếp với nhau. Ngoài ra, sự khác biệt chính là bạn có thể gửi bất kỳ gói dữ liệu tùy ý nào theo byte thô, không được gói gọn trong giao thức HTTP. Các khái niệm về tiêu đề, đường dẫn, chuỗi truy vấn chỉ xảy ra trong quá trình bắt tay, nhưng WebSocket mở ra một luồng dữ liệu.

Sự khác biệt khác là bạn có được quyền truy cập tinh chỉnh hơn vào WebSocket trong Javascript, trong khi với HTTP, nó được trình duyệt xử lý. Tất cả những gì bạn nhận được với HTTP là bất cứ điều gì bạn có thể phù hợp với XHR/ fetch(). Đó cũng có nghĩa là trình duyệt sẽ nhận được để chặn và sửa đổi tiêu đề HTTP mà bạn không thể kiểm soát được nó (ví dụ: Origin, Cookies, vv). Ngoài ra, những gì HTTP / 2 có thể đẩy được gửi đến trình duyệt. Điều đó có nghĩa là JS không luôn luôn (nếu có) biết mọi thứ đang được thúc đẩy. Một lần nữa, nó có ý nghĩa index.cssindex.jsbởi vì trình duyệt sẽ lưu trữ nó, nhưng không nhiều cho các gói dữ liệu.

Đó thực sự là tất cả trong tên. HTTP là viết tắt của Giao thức truyền siêu văn bản. Chúng tôi đang hướng đến khái niệm chuyển tài sản. WebSocket là về việc xây dựng một kết nối ổ cắm, nơi dữ liệu nhị phân được truyền xung quanh hai chiều.


Người mà chúng ta không thực sự thảo luận là SSE (Sự kiện gửi máy chủ). Đẩy dữ liệu vào ứng dụng (JS) không phải là mục đích của HTTP / 2, nhưng nó là dành cho SSE. SSE thực sự được tăng cường với HTTP / 2. Nhưng đó không phải là sự thay thế thực sự cho WebSockets khi điều quan trọng là chính dữ liệu, không phải là điểm cuối biến. Đối với mỗi điểm cuối trong WebSocket, một luồng dữ liệu mới được tạo, nhưng với SSE, nó được chia sẻ giữa phiên HTTP / 2 đã tồn tại.


Tóm tắt ở đây là các mục tiêu cho mỗi:

  • HTTP - Trả lời yêu cầu với một tài sản
  • HTTP / 2 - Trả lời yêu cầu có nhiều tài sản
  • SSE - Trả lời với luồng sự kiện văn bản một chiều (UTF-8)
  • WebSocket - Tạo luồng dữ liệu nhị phân hai chiều
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.