用于双向消息流的 HTTP/2 与 Web 套接字

Lee*_*ren 6 websocket server-sent-events http2 grpc

除了不向 Javascript 公开 HTTP/2 帧的浏览器之外,在什么情况下 Websocket 会比双向流 gRPC(基于 HTTP/2)之类的东西更好地实现实时双向消息流?另外,HTTP 2.0 是全双工(和双向)是否意味着实际上支持服务器推送?那么,对 SSE 之类的东西有什么需求呢?这已经过时了,对吧?

Jon*_*nas 9

这里有很多方面。服务器发送事件,JavaScript Streams API 主要是用于较低级别协议的浏览器 API。

服务器到服务器通信

使用 Websockets 和 HTTP/2 的服务器到服务器通信具有类似的特性。两者都是二进制和高效的协议。HTTP/2 提供每个流的背压,这对于从多个源接收推送消息或有时可能很忙的客户端来说可能很重要。gRPC 是一个基于 HTTP/2 的框架,为开发者提供了更高的抽象。

服务器到浏览器通信

服务器发送事件

服务器发送事件是客户端订阅事件流并持续从服务器接收事件的一种方式。API 是一个更高的抽象和比替代品更容易使用。但是,格式是text 中指定的消息格式。

开发使用服务器发送事件的 Web 应用程序比使用 websockets 更容易。您需要在服务器上编写一些代码来将事件流式传输到前端,但客户端代码的工作方式几乎与处理任何其他事件相同。

示例代码

const evtSource = new EventSource("/v1/stream/topic");

evtSource.onmessage = function(event) {
   // handle event
}
Run Code Online (Sandbox Code Playgroud)

JavaScript 流 API

JavaScript Streams API是一种较新的 JavaScript API,用于支持浏览器和服务器之间的二进制流。这可以与较新的ReadableStream一起使用来自Fetch API。由于这是一个二进制流,它可以有更广泛的用例,并且对于未来几年使用 webassembly 等应用程序可能很重要。

API 有点复杂。示例代码:

fetch("https://www.example.org/").then((response) => {
  const reader = response.body.getReader();
  const stream = new ReadableStream({
    start(controller) {
       // implementation
    }
  })
Run Code Online (Sandbox Code Playgroud)

二进制流的优点是它可以用于自然的二进制数据,例如自定义格式的音频或二进制表示。

在 HTTP/2 或 HTTP/3 Streams 上使用 JavaScript Streams API 比替代方案具有优势,因为它支持每个流(不仅每个 TCP 连接)的背压

gRPC

gRPC 是一种使用 HTTP/2 流的协议,但它没有在 JavaScript Streams API 上实现,因此对于浏览器通信,它需要一些中间件,如grpc-web

网络套接字

WebSockets 是较低级别的抽象,它具有更广泛的浏览器支持,并且支持全双工通信。但由于它是较低级别的抽象,因此通常需要库来处理通信。

  • @ohnezahn我有同样的问题,发现这个链接很有用:https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts#backPressure (2认同)