解释gRPC与HTTP2流

解读

在Unity3D项目里,实时对战、状态同步、热更新资源下载都需要一条“又快又稳”的网络通道。国内大厂(腾讯、网易、米哈)的面试官问这道题,并不是想听你背RFC,而是想确认两件事:

  1. 你是否知道HTTP/2 多路复用能省掉“队头阻塞”这一移动端噩梦;
  2. 你是否能把gRPC的流式调用(尤其是双向流)落地到Unity的协程/异步框架里,解决主线程卡死、GC爆炸、包体膨胀三大痛点。
    答不出“为什么选gRPC而不是WebSocket”,基本会被判为“只用过UnityNetCode,没做过生产级网络”。

知识点

  1. HTTP/2 帧层:

    • 二进制分帧(Frame)替代文本,Header与Data分离,HPACK压缩省50%流量;
    • Stream ID唯一标识一条逻辑流,单TCP连接可并发2^31-1条流,天然多路复用;
    • 流状态机:idle → open → half-close → close,窗口更新帧做流量控制,防止低端安卓机被海量数据冲爆。
  2. gRPC 四式流:

    • Unary:一次请求一次响应,像普通HTTP,适合登录、下单;
    • Server streaming:服务端推,Unity热更新常用,服务端持续下发AB包分片;
    • Client streaming:客户端推,批量上传战斗日志时用,省掉多次POST;
    • Bidirectional streaming帧同步对战核心,两端各自维持一个IAsyncStreamReader/IAsyncStreamWriter,60 fps状态帧在一条HTTP/2流里双向飞,延迟<16 ms
  3. Unity落地细节:

    • 必须grpc-dotnet(基于HTTP/2,非C-core),IL2CPP能编译过App Store;
    • 双向流用await foreach读取,内部用System.Threading.Channels与主线程解耦,避免UnityEngine.Object跨线程访问;
    • 开启HTTP/2 over TLS 1.3才能穿透国内弱网/校园网/双Wi-Fi场景,否则会被中间设备降级到HTTP/1.1导致gRPC直接报错;
    • 包体优化:开启gzip+protobuf,对比JSON省70%流量,256 kB/s的4G网络也能跑30人同屏帧同步。

答案

gRPC是基于HTTP/2的强类型RPC框架,把HTTP/2的“流”抽象成四种调用模式。HTTP/2在TCP之上把数据切成二进制帧,每个帧带Stream ID,同一条连接里可并发无数逻辑流,彻底解决HTTP/1.1的队头阻塞。
gRPC利用这条“流”能力:

  • 普通一次请求叫Unary
  • 服务端连续发叫Server streaming,适合做热更新资源推送
  • 客户端连续发叫Client streaming,可批量上传日志
  • 两端同时连续发叫Bidirectional streaming,是帧同步对战的标配,一条HTTP/2流就能在60 fps下双向传输,延迟可压到网络极限
    在Unity里,我们用grpc-dotnet库,把双向流封装成异步迭代器,通过System.Threading.Channels与主线程通信,避免MonoBehaviour跨线程;同时开启TLS 1.3 + HPACK + protobuf,让256 kB/s弱网下的低端安卓机也能流畅跑30人同屏。简单说,HTTP/2提供了“一条高速车道”,gRPC给出了“四种车型”,Unity只要按帧率把数据塞进双向流,就能在国服、东南亚、欧美服都跑得稳

拓展思考

  1. 国内微信小游戏平台只给WXWebSocket,不支持HTTP/2,如何把gRPC的双向流语义降级到WebSocket+protobuf,同时保证帧同步时序
  2. iOS后台切前台时,HTTP/2连接被系统回收,gRPC Channel状态变为TransientFailure,Unity如何在1秒内静默重连恢复Stream ID而不丢帧?
  3. 字节跳动云游戏场景,UDP被防火墙禁止,只能用HTTP/2,如何把50 MB的热更AB包通过Server streaming做到边下边加载,并且内存占用<150 MB