WebSockets so với các sự kiện được gửi bởi máy chủ / EventSource


838

Cả WebSocketsSự kiện gửi máy chủ đều có khả năng đẩy dữ liệu lên trình duyệt. Đối với tôi dường như họ đang cạnh tranh công nghệ. sự khác biệt giữa chúng là gì? Khi nào bạn sẽ chọn cái này hơn cái kia?


2
Không chắc chắn làm thế nào bạn thấy họ là cạnh tranh. Một cái là đồng bộ và có thể / sẽ được sử dụng cho xfer dữ liệu gần thời gian thực, trong khi cái kia không đồng bộ và sẽ phục vụ một mục đích hoàn toàn khác (gửi tin nhắn giống như bánh mì nướng từ ứng dụng phía máy chủ).
Brian Driscoll

54
WebSockets là hai cách, nó có thể gửi dữ liệu đến máy chủ.
Andre Backlund

13
Một điều tôi thực sự thích về SSE là dễ dàng khắc phục sự cố ... chỉ cần mở một yêu cầu đến máy chủ SSE của bạn bằng cách sử dụng curl. Vì nó chỉ là một định dạng văn bản qua HTTP, nên thật dễ dàng để biết những gì đang diễn ra.
Sam

7
@BrianDriscoll - không đồng bộ / đồng bộ - đó là cái gì? Theo như tôi có thể hiểu cả hai cho phép chuyển không đồng bộ?
Dave Everitt

5
SSE không hoạt động trên IE, websockets cũng vậy
Tyler Gillies

Câu trả lời:


978

Websockets và SSE (Sự kiện gửi máy chủ) đều có khả năng đẩy dữ liệu lên trình duyệt, tuy nhiên chúng không phải là công nghệ cạnh tranh.

Kết nối websockets có thể vừa gửi dữ liệu tới trình duyệt vừa nhận dữ liệu từ trình duyệt. Một ví dụ điển hình của một ứng dụng có thể sử dụng websockets là một ứng dụng trò chuyện.

Kết nối SSE chỉ có thể đẩy dữ liệu lên trình duyệt. Báo giá chứng khoán trực tuyến hoặc twitters cập nhật dòng thời gian hoặc nguồn cấp dữ liệu là những ví dụ điển hình của ứng dụng có thể hưởng lợi từ SSE.

Trong thực tế vì mọi thứ có thể được thực hiện với SSE cũng có thể được thực hiện với Websockets, Websockets đang được chú ý và yêu thích hơn rất nhiều, và nhiều trình duyệt hỗ trợ Websockets hơn SSE.

Tuy nhiên, nó có thể là quá mức cần thiết cho một số loại ứng dụng và phụ trợ có thể dễ thực hiện hơn với một giao thức như SSE.

Hơn nữa, SSE có thể được điền vào các trình duyệt cũ không hỗ trợ nó bằng cách sử dụng JavaScript. Một số triển khai của polyfill SSE có thể được tìm thấy trên trang Modernithr github .

Gotchas:

  • SSE bị giới hạn số lượng kết nối mở tối đa, điều này có thể gây đau đớn đặc biệt khi mở các tab khác nhau vì giới hạn trên mỗi trình duyệt và được đặt ở một số rất thấp (6). Vấn đề đã được đánh dấu là "Không sửa" trong ChromeFirefox . Giới hạn này là cho mỗi trình duyệt + miền, do đó, điều đó có nghĩa là bạn có thể mở 6 kết nối SSE trên tất cả các tab www.example1.comvà 6 kết nối SSE khác tới www.example2.com(cảm ơn Phate).
  • Chỉ WS có thể truyền cả dữ liệu nhị phân và UTF-8, SSE bị giới hạn ở UTF-8. (Cảm ơn Chado Nihi).
  • Một số tường lửa doanh nghiệp với kiểm tra gói gặp sự cố khi xử lý WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks có một số thông tin tốt về SSE. Từ trang đó:

Sự kiện gửi máy chủ so với WebSockets

Tại sao bạn chọn Sự kiện gửi máy chủ qua WebSockets? Câu hỏi hay.

Một lý do SSE đã được giữ trong bóng tối là vì các API sau này như WebSockets cung cấp giao thức phong phú hơn để thực hiện giao tiếp song công hai chiều, hai chiều. Có một kênh hai chiều hấp dẫn hơn cho những thứ như trò chơi, ứng dụng nhắn tin và cho các trường hợp bạn cần cập nhật gần thời gian thực theo cả hai hướng. Tuy nhiên, trong một số trường hợp, dữ liệu không cần phải được gửi từ máy khách. Bạn chỉ cần cập nhật từ một số hành động máy chủ. Một vài ví dụ sẽ là cập nhật trạng thái của bạn bè, đánh dấu chứng khoán, nguồn cấp tin tức hoặc các cơ chế đẩy dữ liệu tự động khác (ví dụ: cập nhật Cơ sở dữ liệu Web SQL phía máy khách hoặc kho đối tượng IndexedDB). Nếu bạn cần gửi dữ liệu đến máy chủ, XMLHttpRequest luôn là một người bạn.

SSE được gửi qua HTTP truyền thống. Điều đó có nghĩa là họ không yêu cầu một giao thức hoặc máy chủ thực hiện đặc biệt để làm việc. Mặt khác, WebSockets yêu cầu các kết nối song công hoàn toàn và các máy chủ Web Socket mới để xử lý giao thức. Ngoài ra, Sự kiện gửi máy chủ có nhiều tính năng mà WebSockets thiếu theo thiết kế như tự động kết nối lại, ID sự kiện và khả năng gửi các sự kiện tùy ý.


Tóm tắt TLDR:

Ưu điểm của SSE so với Websockets:

  • Được truyền qua HTTP đơn giản thay vì giao thức tùy chỉnh
  • Có thể chứa đầy đủ javascript để "backport" SSE cho các trình duyệt chưa hỗ trợ.
  • Được xây dựng để hỗ trợ kết nối lại và id sự kiện
  • Giao thức đơn giản
  • Không có rắc rối với tường lửa công ty kiểm tra gói

Ưu điểm của Websockets so với SSE:

  • Thời gian thực, hai hướng giao tiếp.
  • Hỗ trợ riêng trong nhiều trình duyệt hơn

Các trường hợp sử dụng lý tưởng của SSE:

  • Phát trực tuyến chứng khoán
  • cập nhật nguồn cấp dữ liệu twitter
  • Thông báo cho trình duyệt

SSE gotchas:

  • Không hỗ trợ nhị phân
  • Giới hạn kết nối mở tối đa

131
Trò chuyện hoàn toàn có thể thực hiện được với SSE - bạn có thể sử dụng POST thông thường để gửi tin nhắn đến máy chủ. Chỉ cần có WebSockets nếu bạn đang triển khai trò chuyện với Google Wave.
Kornel

135
Đúng là trò chuyện và các ứng dụng thời gian thực khác có thể được thực hiện với SSE. Tuy nhiên, điều này đòi hỏi POST trả lời "ngoài băng", nghĩa là điều này không được kiểm soát bởi giao thức SSE và dường như không phải là một ví dụ tốt cho lời giải thích cơ bản về sự khác biệt giữa SSE và Websockets. Bạn có thể thực hiện trò chuyện với HTTP cơ bản bỏ phiếu cho máy chủ mỗi giây và POST trả lời mới. Điều này không có nghĩa đó là cách tốt nhất / thanh lịch nhất để làm điều đó.
Alex Recarey

14
Tôi nghĩ rằng giải pháp của pomeL là một sự thỏa hiệp tuyệt vời cho hầu hết các trường hợp, vì JS luôn có thể "đẩy" mọi thứ đến máy chủ bằng AJAX POST. Từ kinh nghiệm của tôi, vấn đề chính nói chung là cần có JS để thăm dò thông tin mới, nhưng SSE quan tâm đến điều đó. : D
Jacob Pritchett

12
@MattDiPasquale Wave đã gửi từng khóa riêng lẻ khi bạn nhập nó thay vì hoàn thành tin nhắn cùng một lúc. 200 byte chi phí POST cho 1 lần nhấn phím sẽ lãng phí so với khoảng 6 cho WebSocket.
Kornel

9
Có vẻ hơi kỳ lạ khi nói rằng chúng không phải là công nghệ cạnh tranh, và sau đó tiến hành mô tả rằng cả hai đều có thể được sử dụng để đạt được các giải pháp tương tự. Tôi sẽ nói rằng làm cho họ cạnh tranh.
Alex

115

Theo caniuse.com:

Bạn có thể sử dụng một polyfill chỉ dành cho khách hàng để mở rộng hỗ trợ SSE cho nhiều trình duyệt khác. Điều này ít có khả năng với WebSockets. Một số polyfill EventSource:

  • EventSource của Remy Sharp không có phụ thuộc thư viện khác (IE7 +)
  • jQuery.EventSource bởi Rick Waldron
  • EventSource của Yaffin (thay thế triển khai gốc, bình thường hóa hành vi trên các trình duyệt)

Nếu bạn cần hỗ trợ tất cả các trình duyệt, hãy cân nhắc sử dụng thư viện như web-socket-js , SignalR hoặc socket.io hỗ trợ nhiều phương tiện vận chuyển như WebSockets, SSE, Forever Frame và AJAX bỏ phiếu dài. Chúng thường yêu cầu sửa đổi cho phía máy chủ là tốt.

Tìm hiểu thêm về SSE từ:

Tìm hiểu thêm về WebSockets từ:

Sự khác biệt khác:

  • WebSockets hỗ trợ dữ liệu nhị phân tùy ý, SSE chỉ sử dụng UTF-8

3
Tôi muốn chỉ ra trong năm 2016> 95% người dùng toàn cầu thực sự hỗ trợ WebSockets. Tất cả các trình duyệt và thiết bị đã hỗ trợ WebSockets trong hơn 4 năm. Socket.IO sẽ dự phòng cho AJAX bỏ phiếu dài và xử lý sự phức tạp của việc mô phỏng WebSockets cho bạn nếu nó không được hỗ trợ, giúp hỗ trợ 100%. Nếu bạn đang sử dụng bất cứ thứ gì trừ WebSockets năm 2016, bạn đang sử dụng công nghệ lỗi thời.
Nick Steele

3
@NickSteele Đó là một tuyên bố cường điệu nhảm nhí. Dựa vào các tiêu chuẩn cũ là hoàn toàn tốt nếu chúng đáp ứng trường hợp sử dụng của bạn và không có nghĩa là bất cứ điều gì đã lỗi thời. Nó chỉ là một tiêu chuẩn khác nhau. Ví dụ: XHR vẫn có thể thực hiện nhiều thứ mà API tìm nạp không thể làm được, vì vậy nó không bị lỗi thời. Nó khác nhau. Trước đây tôi đã từng sử dụng WS, nhưng theo kinh nghiệm, người ta có thể gặp phải những kẻ lừa đảo dưới dạng tường lửa doanh nghiệp tiếng ồn chặn các yêu cầu khi nó không hiểu WS. SSE là siêu hiệu quả cho những gì nó làm, là dễ hiểu và dễ thực hiện và dễ gỡ lỗi. Đối với dataflow một chiều của chúng tôi, nó hoàn hảo.
oligofren

@oligofren Không cần chửi thề. Nếu một cái gì đó được thiết kế để thay thế phiên bản trước đó, và theo định nghĩa, ngành công nghiệp đó được chấp nhận và tốt hơn theo mọi cách, phương pháp cũ đã lỗi thời. Giống như iPhone ban đầu đã lỗi thời, XHR cũng vậy. XHR ra mắt trước Firefox, Chrome, iPhone đầu tiên, trước YouTube, Netflix, Facebook và thậm chí cả MySpace. Khi XHR ra mắt Windows 98 là HĐH tốt nhất, AOL là nhà cung cấp tốt nhất và JSON thậm chí không tồn tại. WebSockets đã thay thế XHR gần một thập kỷ trước. Nếu bạn nhấn snags bằng WS, điều gây ra snag cũng đã lỗi thời. Không có lý do để tụt hậu đến mức đó.
Nick Steele

4
Thay thế BS bằng hyperbole sau đó :-) WS không phải là sự thay thế cho XHR / HTTP, không khác gì máy bay không người lái dành cho xe giao hàng. Đó là trường hợp sử dụng khác nhau. WS không phải là HTTP và có những điểm ngọt ngào khác nhau. Cuối cùng, bạn sẽ thực hiện lại HTTP (kém) trong không gian người dùng nếu bạn thử. Ngoài ra, bạn đang ám chỉ những điều không được đưa ra sự thật: WS chỉ đơn giản là một giao thức hai chiều hỗ trợ đẩy máy chủ. Tôi chưa bao giờ thấy bất kỳ tài liệu thiết kế nào đề cập đến nó đang được phát triển để thay thế cho bất cứ điều gì. Nguồn? Tuổi tác tự nó không phải là một yếu tố. Khi được lựa chọn, chọn cách thực hiện đơn giản nhất kiểm tra tất cả các yêu cầu của bạn.
oligofren

1
Chỉ mới hai năm trước (2017) Tôi đã gỡ lỗi các đống quy trình Node JS trong đó mã Socket.io gây ra sự phân mảnh bộ nhớ lớn trong quy trình IIS, kết thúc cuộc trò chuyện trực tiếp với nhóm Node của Azure. Tổng số phức tạp không phải là miễn phí. Nếu bạn có thể thoát khỏi một tập lệnh 20 dòng đơn giản như là sự phụ thuộc của bạn vào máy chủ, trong khi vẫn có thể phục vụ 100 nghìn khách hàng, tôi sẽ thực hiện nó. Mặc dù vậy, tôi yêu WS vì những gì nó làm, nhưng hãy nhìn vào những gì bạn cần trước khi chọn giải pháp.
oligofren

16

Opera, Chrome, Safari hỗ trợ SSE, Chrome, Safari hỗ trợ SSE bên trong SharedWorker Firefox hỗ trợ XMLHttpRequest readyState tương tác, vì vậy chúng tôi có thể tạo ra polyfil EventSource cho Firefox


8

Websocket VS SSE


Web Sockets - Đây là một giao thức cung cấp kênh liên lạc song công hoàn toàn qua một kết nối TCP. Ví dụ, giao tiếp hai chiều giữa Máy chủ và Trình duyệt Vì giao thức phức tạp hơn, máy chủ và trình duyệt phải dựa vào thư viện websocket.socket.io

Example - Online chat application.

SSE (Sự kiện gửi máy chủ ) - Trong trường hợp máy chủ gửi sự kiện, việc liên lạc được thực hiện từ máy chủ đến trình duyệt và trình duyệt không thể gửi bất kỳ dữ liệu nào đến máy chủ. Kiểu giao tiếp này chủ yếu được sử dụng khi nhu cầu chỉ hiển thị dữ liệu được cập nhật, sau đó máy chủ sẽ gửi tin nhắn bất cứ khi nào dữ liệu được cập nhật. Chẳng hạn, giao tiếp một chiều giữa Máy chủ với Trình duyệt. Giao thức này ít phức tạp hơn, do đó, không cần phải dựa vào thư viện bên ngoài, chính JAVASCRIPT cung cấp EventSourcegiao diện để nhận các tin nhắn được gửi từ máy chủ.

Example - Online stock quotes or cricket score website.

4

Một điều cần lưu ý:
Tôi đã có vấn đề với websockets và tường lửa của công ty. (Sử dụng HTTPS giúp nhưng không phải lúc nào cũng vậy.)

Xem https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94

Tôi cho rằng không có nhiều vấn đề với Sự kiện gửi máy chủ. Nhưng tôi không biết.

Điều đó nói rằng, WebSockets là rất nhiều niềm vui. Tôi có một trò chơi web nhỏ sử dụng websockets (thông qua Socket.IO) ( http://minibman.com )


1
Tôi cũng đã có vấn đề với tường lửa của công ty.
oligofren

1
Một vấn đề tôi gặp phải với Sự kiện gửi máy chủ là một số proxy / tường lửa có thể chặn nó vì nó không có tiêu đề Độ dài nội dung
Drew LeSueur

2

Dưới đây là một cuộc nói chuyện về sự khác biệt giữa các ổ cắm web và các sự kiện gửi máy chủ. Vì Java EE 7, API WebSocket đã là một phần của đặc tả và có vẻ như các sự kiện được gửi bởi máy chủ sẽ được phát hành trong phiên bản tiếp theo của phiên bản doanh nghiệp.


-3

Giới hạn kết nối tối đa không phải là vấn đề với http2 + sse.

Đó là một vấn đề trên http 1


Http2 cho phép nhiều yêu cầu trên cùng một miền được coi là luồng. Kỹ thuật này được gọi là ghép kênh. Điều này giúp tiết kiệm giới hạn kết nối của mỗi trình duyệt trên mỗi tên miền, đó là lý do tại sao mọi người thực hiện việc bảo vệ tên miền với Http1.
dùng1948585

1
Các luồng HTTP / 2 cũng bị giới hạn về số lượng, điều này bảo vệ các máy chủ khỏi bị bắn phá bởi một trình duyệt duy nhất và buộc các trình duyệt hạn chế ghép kênh của chúng ở một số luồng hạn chế - trong trường hợp của chúng tôi, giống như các kết nối HTTP / 1.1 .. . đưa bạn trở lại giới hạn kết nối SSE.
Bí ẩn

Tôi giả sử kết nối websocket cũng tiêu tốn tài nguyên máy chủ. samsaffron.com/archive/2015/12/29/websockets-caestion-required . Nó luôn luôn tốt để có khả năng cấu hình nhiều như túi của bạn cho phép.
dùng1948585

có khả năng SSE sẽ tiêu thụ tài nguyên tương tự trên hầu hết các máy chủ (nếu không có nhiều tài nguyên hơn do ngăn xếp HTTP vẫn còn và đó là những hạn chế).
Bí ẩn

1
Câu trả lời này là chính xác. Giới hạn 6 kết nối HTTP không còn tồn tại khi sử dụng HTTP / 2. Bằng chứng: codepen.io/dunglas/pen/yLYxdxK?editors=1010 Với HTTP / 2, máy chủ có thể thỏa thuận số lượng luồng đồng thời tối đa (100 theo mặc định).
Kévin Dunglas
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.