HTTP2 客户端上传文件达到SETTINGS_INITAL_WINDOW_SIZE后服务器如何回应?

我正在实现一个HTTP2服务器客户端上传文件的部分,当上传文件大小小于默认的SETTINGS_INITAL_WINDOW_SIZE(65535)时没问题。

在客户端上传文件时数据量达到 SETTINGS_INITAL_WINDOW_SIZE 之后,浏览器会停止上传(因为流量窗口控制流量),我尝试向 Chrome 浏览器发送一个 Window Update 帧来告诉浏览器可以继续发送数据:
image.png
但是 Chrome 日志上接收到了这个 Window Update 帧后上传文件的流1还是处于STALLED_BY_STREAM_WINDOW状态,不继续发送Data帧上传数据

无论我发送的WindowUpdate帧处于流ID为0还是上传文件的流,Chrome都不继续发送Data帧上传数据。

请问怎么做才能使得浏览器继续上传data帧?难道需要服务器发送一个Priority帧改变优先级浏览器才继续发送数据吗?

我观察到即使浏览器日志内有发送更新流量窗口的信息,但实际上浏览器并没有发送这些信息。

或者能不能提供一个正常上传文件到服务器的日志,chrome于chrome://net-export/ 录制日志,感激不尽。

阅读 1.5k
1 个回答

经过一夜的思考,我尝试了很多方案,结果让我没想到的是流0和上传文件的流在流量控制里差不多是父子关系。。。

因为上传文件时流0的流量窗口用完了(流0的流量窗口随各个流的数据传输递减),所以Chrome会先检测流0的流量窗口,可想而知为0,所以便堵塞了文件上传流的上传。

classDiagram
    Stream0 <|-- Stream1
    Stream0 <|-- Stream2
    Stream0 <|-- Stream3
    Stream0 : int TotalWindowSize
    Stream0 : ...

    class Stream1{
      int WindowSize
      ...
    }
    class Stream2{
      int WindowSize
      ...
    }
    class Stream3{
      int WindowSize
      ...
    }
            

简单来说,就是流0是万流之母,其他流的窗口大小减少了,流0也得减少。

把流0比作水管,其他流比作总(流0)水管的分支,窗口大小比作手捏在水管上,当其他流的窗口大小减少,流0的窗口大小减少到0,此时总水管就被捏住不能出水,哪怕分支水管的手指还没被捏堵塞,也不会出水。

这一条是翻了书也没有说的,大部分翻译看到的文档也没有非常明确的说明。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进