【发布时间】: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 之间的关系不明确。