☰
gRPC-Web 流式传输路线图全解读:服务端流式现状、WebTransport 双向流与 WebSocket 取舍
2026/9/25 7:56:16 网站建设 项目流程
  • 后端
  • 微服务

【免费下载链接】grpc-web

gRPC for Web Clients

项目地址:https://gitcode.com/gh_mirrors/gr/grpc-web
点击查看免费下载

gRPC-Web 是 gRPC 的浏览器端 JavaScript 实现,浏览器客户端需要借助 Envoy 等代理才能访问 gRPC 服务。本文以仓库内 doc/streaming-roadmap.md 为核心,系统梳理 gRPC-Web 对流式 RPC 的完整规划:服务端流式(Server-streaming)当前已支持并将持续增强、客户端流式与半双工流式暂不支持的决策逻辑、计划基于 WebTransport 实现全双工双向流式的技术路线,以及团队为何明确放弃 WebSocket 方案的深层原因,并结合仓库源码给出可验证的实现证据。

一、路线图总览:四类流式能力的现状与规划

gRPC 共有四类 RPC 模式,它们在 gRPC-Web 中的支持状态截然不同:

RPC 模式数据流向gRPC-Web 当前状态未来规划
Unary(一元)单请求 → 单响应✅ 已支持持续维护
Server-streaming(服务端流式)单请求 → 多响应✅ 已支持(仅grpcwebtext模式)持续改进,见下文
Client-streaming(客户端流式)多请求 → 单响应❌ 不支持随 WebTransport 全双工流式一并解决
Full-duplex / half-duplex(双向流式)多请求 ↔ 多响应❌ 不支持依赖 WebTransport(2023+ 规划)

这份路线图(doc/streaming-roadmap.md)明确列出了三个演进方向:服务端流式的增强、客户端流式与半双工流式的未来方案、基于 WebTransport 的全双工流式,并附带了对 WebSocket 的明确态度。主路线图文档 doc/roadmap.md 中"Streaming Support"与"Bidi Streaming"两节也分别指向本文档,可见流式能力是 gRPC-Web 整体演进的核心议题之一。

仓库中的 echo 示例(net/grpc/gateway/examples/echo/echo.proto)完整定义了这四类方法,其中客户端流式与双向流式的定义旁都注有同一行说明:"Notice: Client side streaming and Bidi streaming are not supported at the moment."(目前不支持客户端流式与双向流式)。这份 proto 与路线图互为印证:能力边界在服务定义和客户端运行时两个层面都是一致的。

二、服务端流式(Server-streaming):已支持,仍在演进

2.1 当前支持范围

服务端流式是 gRPC-Web 目前支持的两种 RPC 模式之一。仓库根目录 README.md 明确说明:

gRPC-web currently supports 2 RPC modes: Unary RPCs and Server-side Streaming RPCs(NOTE: Only whengrpcwebtextmode is used.)

即服务端流式调用必须在grpcwebtext(application/grpc-web-text)线格式模式下才能工作,使用二进制grpcweb(application/grpc-web+proto)模式时仅支持一元调用。这一点在 README.md 的 Wire Format Mode 小节有详细描述:

  • mode=grpcwebtext:payload 经 base64 编码,Content-type: application/grpc-web-text,一元与服务端流式调用均支持;
  • mode=grpcweb:二进制 protobuf,Content-type: application/grpc-web+proto,仅支持一元调用。

客户端侧的服务端流式调用代码模式如下(摘自 README.md):

var stream = echoService.serverStreamingEcho(streamRequest, metadata); stream.on('data', function(response) { console.log(response.getMessage()); }); stream.on('status', function(status) { console.log(status.code); console.log(status.details); console.log(status.metadata); }); stream.on('end', function(end) { // stream end signal }); // to close the stream stream.cancel()

2.2 服务端流式的底层实现链路

从源码看,服务端流式调用的入口在 javascript/net/grpc/web/grpcwebclientbase.js 的serverStreaming()方法:它先解析出 hostname,将"发起流式请求"包装为 invoker 后交给拦截器链,最终返回一个GrpcWebClientReadableStream。该流对象在 javascript/net/grpc/web/grpcwebclientreadablestream.js 中实现:

  • on()注册事件:支持data、status、metadata、end、error五类回调(源码 grpcwebclientreadablestream.js),与 README 示例中的用法一一对应;
  • cancel()取消流:将aborted_置位并调用xhr.abort()(源码 grpcwebclientreadablestream.js),取消后的 ABORT 错误不会被当作异常抛出;
  • XHR 事件驱动:流数据在READY_STATE_CHANGE事件中增量解析,流结束状态在COMPLETE事件中统一判定,并从响应头提取grpc-status/grpc-message与初始 metadata。

响应体的帧解析由 javascript/net/grpc/web/grpcwebstreamparser.js 完成,它实现goog.net.streams.StreamParser接口,状态机在INIT(帧字节)→LENGTH(4 字节长度)→MESSAGE(消息体)之间流转,支持流式分段输入(partial stream segments)。帧类型定义在源码 grpcwebstreamparser.js:

GrpcWebStreamParser.FrameType = { DATA: 0x00, // 数据帧 TRAILER: 0x80, // trailer 帧 };

即服务端流式的响应在线上形如0x00 <message1> 0x00 <message2> ... 0x80 <trailers>,每条消息独立成帧,最终以 trailer 帧携带 gRPC 状态收尾。

2.3 路线图规划的服务端流式改进项

路线图文档为服务端流式列出的改进方向与时间预期如下:

  • Fetch 取消支持(2024):当前客户端运行时基于 XHR(goog.net.XhrIo)实现,流取消依赖xhr.abort();迁移到 Fetch 后需要补齐 Fetch 的AbortController取消语义;
  • 性能优化与 whatwg Fetch/streams 支持,包括 Service Workers(2024):Fetch/ReadableStream 相比 XHR 在流式吞吐、内存占用上有优势,也能让 gRPC-Web 请求进入 Service Worker 缓存/拦截体系;
  • 完善 keep-alive 支持(通过 Envoy,2024+):长连接保活依赖代理层配合,见 doc/roadmap.md 中 Envoy 相关说明;
  • 弥合 Fetch 与 XHR 之间的运行时行为差异(2024+):包括错误映射、超时语义、响应头可见性等细粒度行为对齐。

这些条目都属于持续打磨性质,说明服务端流式是当前"主战场":功能可用,但传输层基座(从 XHR 走向 Fetch/streams)的替换是未来两年的主线。

三、客户端流式与半双工流式:为何暂不支持

路线图对客户端流式的态度非常明确:

We don't plan to support client-streaming via Fetch/upload-streams. As a result, half-duplex bidi streaming won't be supported via Fetch/streams either.

也就是说,团队不计划通过 Fetch 的upload-streaming(请求体流式上传)能力去支持客户端流式;因此依赖"客户端先传完再收响应"的半双工双向流式,也不会借道 Fetch/streams 落地。这两类能力将被统一推迟到 WebTransport 全双工流式方案中一并解决。

这一决策的直接背景是附录中记录的 Chrome Origin Trial(详见第五节):upload-streaming规范尚未定稿,且 HTTP/1.1 下的安全性仍在讨论,无法作为可靠的技术底座。

从服务定义侧同样能看到印证:echo 示例中ClientStreamingEcho、FullDuplexEcho、HalfDuplexEcho三个方法均带"not supported at the moment"注释(echo.proto),生成客户端代码时不会为它们产生可用的流式调用实现。

四、全双工流式:押注 WebTransport

路线图规划的全双工(双向)流式方案是基于 WebTransport 实现,时间预期为 2023+(按文档编写时的表述)。WebTransport 的价值在于:它在浏览器与服务器之间提供真正的双向、多路复用字节流能力,天然契合 gRPC 全双工 RPC 的"客户端流 + 服务端流同时进行"的语义,而这正是 HTTP 请求/响应模型(含 Fetch/streams)无法覆盖的缺口。

主路线图 doc/roadmap.md 的 "Bidi Streaming" 一节同样声明"We plan to leverage WebTransport for bi-directional streaming",两份文档口径一致。

需要说明的是:从当前仓库代码结构看,javascript/net/grpc/web/ 目录下的运行时仍以 XHR 传输为主(GrpcWebClientBase内部直接构造XhrIo并xhr.send()),尚未包含 WebTransport 传输适配器;WebTransport 支持仍处于路线图规划阶段而非已落地功能。这也意味着客户端流式与双向流式在本文撰写时仍是"规划中"状态,读者不应期望在现网环境直接使用。

五、WebSocket:明确不采用,以及背后的 HTTP 兼容性逻辑

路线图给出了一个非常明确的负面决策:

We have no plan to support full-duplex streaming over WebSockets (over TCP or HTTP/2). We will not publish any experimental spec for gRPC over WebSockets either.

即:不打算在 WebSocket(无论跑在 TCP 还是 HTTP/2 之上)上支持全双工流式,也不会发布任何"gRPC over WebSocket"的实验性规范。理由集中在一点——WebSocket 与 HTTP(以及承载 Web 的普遍基础设施)不兼容:

  1. HTTP 回退总是必要:WebSocket 一旦不可用(网络设备、企业代理、部分移动网络等),必须回退到 HTTP 通道,这意味着每个使用 WebSocket 的方案都要维护两套传输逻辑;
  2. HTTP/2 上的 WebSocket 隧道普及度不足:虽然 IETF 有将 WebSocket 封装进 HTTP/2 的提案,但并未被广泛实现,无法形成可靠基线;
  3. 对比之下,WebTransport 构建在 HTTP/3 生态之上,与现有 Web 基础设施(TLS、代理、CDN)的兼容路径更清晰,这也是团队选择 WebTransport 而非 WebSocket 的关键考量。

六、附录解读:Chrome Origin Trial 与upload-streaming的来龙去脉

路线图附录记录了团队参与推进 whatwgfetch/upload-streamAPI 规范的背景:他们参与了 Chrome 的 Origin Trial(试验编号 3524066708417413121),目标是让浏览器能通过 Fetch API 流式上传请求体。

阻塞最终规范定稿的核心问题是:是否允许 upload-streaming 跑在 HTTP/1.1 上。团队立场是 HTTP/2 与 HTTP/1.1 都应启用 upload-streaming,并给出一个针对 gRPC-Web 场景的独特论据:

the server can't control the client deployment. As a result, if upload-streaming is only enabled over HTTP/2, a gRPC service will have to implement a non-streaming method as a fallback for each client-streaming method.

翻译过来就是:gRPC-Web 的服务端无法控制浏览器客户端的部署环境。如果 upload-streaming 只在 HTTP/2 下可用,那么任何提供客户端流式方法的 gRPC 服务,都必须为每个客户端流式方法额外实现一个非流式(一元)方法作为回退——这会显著增加服务端负担。因此他们主张 HTTP/1.1 同样支持上传流式。

正是由于该规范尚未定稿、且存在 HTTP 版本兼容性分歧,客户端流式方案无法建立在 Fetch/upload-streams 之上,最终被并入 WebTransport 路线——这正是第六节"暂不支持客户端流式"决策的完整逻辑链条。

七、结论与决策摘要

结合 doc/streaming-roadmap.md 与仓库实现,可以得出 gRPC-Web 流式能力的完整时间线认知:

  1. 服务端流式:当前可用(仅grpcwebtext模式),底层由GrpcWebClientReadableStream+GrpcWebStreamParser提供事件驱动解析;2024 年起逐步将传输基座从 XHR 迁移到 Fetch/streams,补齐取消、Service Worker、keep-alive 等能力;
  2. 客户端流式 / 半双工流式:不通过 Fetch/upload-streams 支持,等待 WebTransport 方案统一解决;
  3. 全双工流式:规划基于 WebTransport 实现(2023+ 规划),当前仓库代码尚无对应传输层实现;
  4. WebSocket:明确弃用,核心原因是与 HTTP 基础设施的不兼容及 HTTP/2 隧道普及度不足。

对于正在基于 gRPC-Web 做技术选型的读者,这份路线图的实用价值在于:短期可放心使用一元与服务端流式(注意选择grpcwebtext线格式并配置好 Envoy 代理,参考 net/grpc/gateway/examples/echo/envoy.yaml 中的grpc_web过滤器与 CORS 配置);若业务强依赖客户端流式或双向流式,则当前阶段需要评估服务端方案(如 gRPC over HTTP/2 直连、或等待 WebTransport 生态成熟),这与上游 doc/roadmap.md 的整体规划一致。

  • 后端
  • 微服务

【免费下载链接】grpc-web

gRPC for Web Clients

项目地址:https://gitcode.com/gh_mirrors/gr/grpc-web
点击查看免费下载

相关推荐

上一篇:Awoo Installer:1个NSP安装器,3种方式装Switch游戏
下一篇:跨平台私有音乐服务终极指南:any-listen快速搭建与深度使用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询