QGrpcHttp2Channel Class
QGrpcHttp2Channel 类为 gRPC™ 通信提供了一个 HTTP/2 传输层。更多内容...
| 标题: | #include <QGrpcHttp2Channel> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Grpc) target_link_libraries(mytarget PRIVATE Qt6::Grpc) |
| 自: | Qt 6.5 |
| 在 QML 中: | GrpcHttp2Channel |
| 继承自: | QAbstractGrpcChannel |
公共函数
| QGrpcHttp2Channel(const QUrl &hostUri) | |
| QGrpcHttp2Channel(const QUrl &hostUri, const QGrpcChannelOptions &options) | |
| virtual | ~QGrpcHttp2Channel() override |
| QUrl | hostUri() const |
详细描述
QGrpcHttp2Channel 类实现了QAbstractGrpcChannel 接口,从而支持 gRPC™ 通过HTTP/2 帧结构进行通信。
与前身 HTTP/1.1 相比,HTTP/2 具有多项优势,这使得 QGrpcHttp2Channel 非常适合高性能、实时应用程序,这些应用程序需要通过多路复用 TCP 连接实现高效通信,同时又不牺牲安全性或可靠性。
可以通过使用包含所需自定义设置的QGrpcChannelOptions 来构建该通道,从而对其进行自定义,例如支持SSL、自定义serializationFormat 或其他选项。
注意: QGrpcChannelOptions::filterServerMetadata 默认处于启用状态。
传输方案
QGrpcHttp2Channel 的实现会根据提供的hostUri 、scheme 以及选项,优先选择不同的传输方式。适用以下标准:
| 方案 | 描述 | 默认端口 | 要求 | 示例 |
|---|---|---|---|---|
http | 基于 TCP 的未加密 HTTP/2 | 80 | 无 | http://localhost |
https | 基于 TCP 的 TLS 加密 HTTP/2 | 443 | QSslSocket 支持AND(方案OR sslConfiguration) | https://localhost |
unix | 文件系统路径中的 Unix 域套接字 | ✗ | QLocalSocket 支持且方案 | unix:///tmp/grpc.socket |
unix-abstract | 位于抽象命名空间中的 Unix 域套接字 | ✗ | QLocalSocket 支持AND AbstractNamespace 支持ANDscheme | unix-abstract:app_grpc_channel |
Content-Type
HTTP/2 协议中gRPC 的内容类型决定了消息序列化格式。它必须以application/grpc 开头,并可包含后缀。格式遵循以下规范:
"content-type": "application/grpc" [("+proto" / "+json" / {custom})]例如:
application/grpc+proto指定 Protobuf 编码。application/grpc+json表示 JSON 编码。
序列化格式可通过在元数据中指定content-type ,或直接设置serializationFormat 来配置。默认情况下,使用application/grpc 内容类型。
若要通过content-type 元数据将QGrpcHttp2Channel配置为JSON序列化格式:
auto jsonChannel = std::make_shared<QGrpcHttp2Channel>(
QUrl("http://localhost:50051"_L1),
QGrpcChannelOptions().setMetadata({
{ "content-type"_ba, "application/grpc+json"_ba },
})
);对于自定义序列化器和content-type ,您可以直接设置序列化格式:
class DummySerializer : public QAbstractProtobufSerializer
{
...
};
QGrpcSerializationFormat dummyFormat("dummy", std::make_shared<DummySerializer>());auto dummyChannel = std::make_shared<QGrpcHttp2Channel>(
QUrl("http://localhost:50051"_L1),
QGrpcChannelOptions().setSerializationFormat(dummyFormat)
);这将使用DummySerializer 对带有dummy 后缀的消息进行编码和解码。对于 HTTP/2 传输,这将生成application/grpc+dummy 内容类型。
注意:自定义 序列化器需要服务器支持指定的格式。
保留的元数据键
元数据以 HTTP/2 头的形式传输:键为不区分大小写的 ASCII 字符串,值可以是 ASCII 字符串或二进制数据。以下键由 HTTP/2 或gRPC 协议保留,在构建请求时将从用户元数据中移除:
- HTTP/2 伪标头(任何以
:开头的键)。 - 任何以
grpc-或qtgrpc-为前缀的键。 te、content-type、user-agent。
在通道构建时,仍会参考用户提供的content-type 来自动检测序列化器(参见Content-Type );但它不会作为 Custom-Metadata 条目进行转发。
有关 HTTP/2 报头的更多信息,请参阅RFC 7540 第 8.1.2 节。
接收窗口
HTTP/2 流量控制限制了发送方在接收方确认之前可传输的数据量。通道向服务器发布两个此类限制,即接收窗口:
- 流窗口限制单个 RPC 中未确认的数据量。
- 连接窗口限制了共享同一连接的所有 RPC 的未确认数据总量。
窗口限制的是传输中的数据量,而非传输大小。由于确认需要一次网络往返,因此它同时也限制了吞吐量:
maximum throughput = window / round-trip time这两个窗口均通过环境变量以字节为单位进行配置:
QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE用于流窗口;(默认值为4 MiB)QT_GRPC_HTTP2_CONNECTION_RECEIVE_WINDOW_SIZE用于流窗口;(默认值为16 MiB的四倍)
仅设置QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE 会自动将连接窗口调整为流窗口大小的四倍。若要使用不同的比例,请显式设置QT_GRPC_HTTP2_CONNECTION_RECEIVE_WINDOW_SIZE 。
这些默认值会使本地网络和大多数互联网路径达到饱和。但在往返时间较长的高速链路上,这些默认值则显不足。例如,某应用程序从远端服务器接收大容量消息:
link: 1 Gbit/s (125 MB/s), 100 ms round-trip time服务器发送一个流窗口的数据,然后等待一个往返时间以获取确认。使用默认窗口时,它每 100 毫秒最多可传输 4 MiB:
4 MiB / 0.1 s = 42 MB/s, 34% of the 125 MB/s the link carries要使链路饱和,窗口必须容纳链路在一个往返过程中传输的所有数据,即链路的带宽延迟积(BDP):
BDP = 125 MB/s x 0.1 s = 12.5 MB
QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE=12500000
12.5 MB / 0.1 s = 125 MB/s, the link is saturated并发 RPC 共享单个连接接收窗口。只要每个流都被持续读取,总在途数据量就始终受 BDP 限制。但如果某个流未被读取,其缓冲数据将占用部分共享连接窗口,并可能阻塞其他流。 一个不错的经验法则是:将连接窗口的大小设置为所有并发活动流窗口大小的总和。对于上述链路上的八个并行传输:
QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE=12500000 (12.5 MB = BDP)
QT_GRPC_HTTP2_CONNECTION_RECEIVE_WINDOW_SIZE=100000000 (8 x 12.5 MB)当某个 RPC 是唯一活跃的传输时,它可以使用全部 125 MB/s 的带宽。如果有八个并发 RPC,它们将以每个约 15 MB/s 的速率共享链路。在最坏的情况下,如果应用程序停止从所有流中读取数据,通道可能会缓冲多达 100 MB 的数据。
另一种方法是调整流窗口大小,使其总和能够容纳在等于 BDP 的连接窗口内。这既限制了最大缓冲数据量,又确保每个 RPC 即使单独传输时,其传输速率也仅限于分配的份额:
QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE=1562500 (12.5 MB / 8)
QT_GRPC_HTTP2_CONNECTION_RECEIVE_WINDOW_SIZE=12500000 (= BDP)每个 RPC 的传输速率上限约为 15 MB/s,无论其是单独传输还是与其他七个 RPC 同时传输。其优点在于,通道中未读取数据的缓冲量永远不会超过约 12.5 MB。
当降低传输延迟比内存使用更重要时,请使用全尺寸流窗口;当限制内存消耗是优先事项时,请使用较小的流窗口。无论哪种情况,都要确保连接窗口足够大,能够容纳多个流窗口;否则,单个未读流就可能耗尽共享的连接窗口,从而阻塞所有其他 RPC。
这两个窗口均支持最大值为2147483647 字节。流窗口的下限为1024 字节,这允许内存受限的接收方限制每个流的缓冲量;连接窗口的下限为65535 字节,即该协议的初始窗口大小。
环境变量后备方案
某些通道设置可通过环境变量进行配置。这些变量会在每个通道构建时进行评估。如果未设置环境变量,则使用内置默认值。
| 环境变量 | 选项 | 默认回退值 |
|---|---|---|
QT_GRPC_MAXIMUM_RECEIVE_MESSAGE_SIZE | maximumReceiveMessageSize | 4 MiB (4'194'304 字节) |
QT_GRPC_MAXIMUM_METADATA_SIZE | 无 | 16 KiB(16'384 字节) |
QT_GRPC_INITIAL_RECONNECT_BACKOFF_MS | 无 | 1 秒 (1'000 毫秒) |
QT_GRPC_MAXIMUM_RECONNECT_BACKOFF_MS | 无 | 120秒(120'000毫秒) |
QT_GRPC_CONNECT_TIMEOUT_MS | 无 | 20秒(20'000毫秒) |
QT_GRPC_HTTP2_STREAM_RECEIVE_WINDOW_SIZE | 无 | 4 MiB(4'194'304 字节) |
QT_GRPC_HTTP2_CONNECTION_RECEIVE_WINDOW_SIZE | 无 | 16 MiB(16'777'216 字节) |
另请参阅 QAbstractGrpcChannel 、QGrpcChannelOptions 以及QGrpcSerializationFormat 。
成员函数文档
[explicit] QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &hostUri)
使用hostUri 构建QGrpcHttp2Channel。更多信息请参阅Transportation scheme 部分。
[explicit] QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &hostUri, const QGrpcChannelOptions &options)
使用 `hostUri ` 和 `options` 构造 `QGrpcHttp2Channel`。更多信息请参阅Transportation scheme 部分。
[override virtual noexcept] QGrpcHttp2Channel::~QGrpcHttp2Channel()
销毁QGrpcHttp2Channel 对象。
QUrl QGrpcHttp2Channel::hostUri() const
返回该频道的主机 URI。
该 URI 会根据Transportation scheme 进行规范化处理:方案可能会被调整,并且可能会填入默认端口。将返回的 URI 传回QGrpcHttp2Channel 将选择相同的传输配置。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.