Delphi 的 TNetHTTPClient 后代支持 http2

Posted

技术标签:

【中文标题】Delphi 的 TNetHTTPClient 后代支持 http2【英文标题】:Delphi's TNetHTTPClient descendant supporting http2 【发布时间】:2019-10-23 15:15:02 【问题描述】:

我正在尝试从 Delphi 10.3.1 Windows 客户端应用程序通过 gRPC 与 Google Cloud Speech 进行通信。为此,通信需要使用http2作为协议,数据需要2路异步传输。

Delphi 包含 TNetHTTPClient,它被 TNetHTTPRequest 用于 http 通信。使用调试器发现 System.Net.HttpClient.Win.pas 中的 TWinHTTPClient 是内部用于通信的。

为了添加对 http2 的支持,我在 System.Net.HttpClient.Win.pas 的 TWinHTTPClient.DoExecuteRequest 中插入了 2 行,第 1360 行:

    LOptionValue := 1;//WINHTTP_PROTOCOL_FLAG_HTTP2;
    WinHttpSetOption(LRequest.FWRequest, WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL, @LOptionValue, sizeof(LOptionValue));

添加上述代码后,组件使用的是http2,我通过gRPC调用Google Cloud Speech Sync Request端点成功验证。

但是,我的方法有两个主要缺点:

    需要修改Delphi源码。 它不支持异步双向数据传输,对此我认为需要在不关闭连接的情况下触发 OnDataReceived 事件。

我试图找到一个可以将 TNetHTTPClient 替换为修改过的组件 TMyNetHTTPClient 的点,但我没有成功。

那么,问题来了:如何在TWinHTTPClient的基础上创建一个TNetHTTPClient替代品,它支持http2,并且在不关闭连接的情况下实现OnDataReceived事件?

【问题讨论】:

如何创建一个基于 TWinHTTPClient 的 TNetHTTPClient 替代品,它支持 http2 并在不关闭连接的情况下实现 OnDataReceived 事件?” - 你不能。为什么不直接使用 WinHTTP API? 那么,不可能创建一个 TNetHTTPClient 后代来实现所请求的功能吗?令我失望的是,Delphi 的 TNetHTTPRequest/TNetHTTPClient 似乎被设计为易于使用的 WinHTTP API 包装器。 您可以创建后代。只需编写包装适当 WinHTTP 调用以支持 http2 的代码。是什么阻止你这样做? 我无法创建 TWinHTTPClient 后代,因为它位于 System.Net.HttpClient.Win.pas 的实现部分。我试图创建一个 TNetHTTPClient 后代,但我无法用 TWinHttpClient.DoExecuteRequest 覆盖 DoExecuteRequest。 基本上,阻止我的是:TNetHttpClient 和 TWinHTTPClient 之间的关系不明确。 【参考方案1】:

它不是基于 TNetHTTPClient,但 grijjy 已经为 Windows 和 Linux 开源了一个 HTTP2 Delphi 客户端。

你可以在这里找到它 - https://github.com/grijjy/DelphiScalableClientSockets

【讨论】:

以上是关于Delphi 的 TNetHTTPClient 后代支持 http2的主要内容,如果未能解决你的问题,请参考以下文章

delphi 点击按钮后dbgrid显示所选内容

将 Delphi 7 应用程序移植到 Delphi 2007 后性能下降 [关闭]

重装系统后,delphi7打开报错

delphi释放窗体后如何再次载入窗体

delphi 控制服务程序,让服务启动失败后总是恢复。

delphi7 DbgirdEH安装后不显示控件