首页 > 解决方案 > 用于双向消息流的 HTTP/2 与 web-sockets

问题描述

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

标签: websocketgrpchttp2server-sent-events

解决方案


这里有很多方面。服务器发送事件,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
}

JavaScript 流 API

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

API 有点复杂。示例代码:

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

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

在 HTTP/2 或 HTTP/3 Streams 上使用 JavaScript Streams API 的优势在于它支持每个流的背压(不仅是每个 TCP 连接)。

gRPC

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

网络套接字

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


推荐阅读