WinHTTP over HTTP/2 多路复用
Posted
技术标签:
【中文标题】WinHTTP over HTTP/2 多路复用【英文标题】:WinHTTP over HTTP/2 with multiplexing 【发布时间】:2020-05-13 14:00:56 【问题描述】:我想知道 Windows API WinHTTP 是否可以使用 HTTP/2 多路复用(一个 TCP 连接上的多个请求)。如果是这样,是否有示例代码如何归档?
我发现了来自 Microsoft (https://docs.microsoft.com/en-us/windows/win32/winhttp/about-winhttp) 的这条消息:
注意
WinHTTP 不可重入,除非在异步完成回调期间。也就是说,当线程有一个对 WinHttpSendRequest、WinHttpReceiveResponse、WinHttpQueryDataAvailable、WinHttpSendData 或 WinHttpWriteData 等 WinHTTP 函数的调用挂起时,它绝不能再次调用 WinHTTP,直到第一次调用完成。可能发生第二次调用的一种情况如下:如果应用程序将异步过程调用 (APC) 排队到调用 WinHTTP 的线程,并且如果 WinHTTP 在内部执行可警报等待,则 APC 可以运行。如果 APC 例程也调用 WinHTTP,它会重新进入 WinHTTP API,WinHTTP 的内部状态可能会被破坏。
这就是为什么我不确定是否可以异步调用 WinHttpReadData。
【问题讨论】:
【参考方案1】:我最近发现了 WinHTTP 对 HTTP2 的支持,并且想知道是否可以进行完全多路复用,因为几乎没有关于它的文档。由于同步模式下的请求/响应不支持在不读取第一个请求的情况下发送第二个请求,因此我重新设计了我的应用程序以使用异步模式,并使用以下选项一次发出多个请求:
const DWORD tlsProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 |
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
const DWORD enableHTTP2Flag = WINHTTP_PROTOCOL_FLAG_HTTP2;
const DWORD decompression = WINHTTP_DECOMPRESSION_FLAG_ALL;
HINTERNET hSession = WinHttpOpen(L"WinHttp Test",
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
WINHTTP_FLAG_ASYNC);
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
WinHttpSetOption(hSession, WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL,
(LPVOID)&enableHTTP2Flag, sizeof(enableHTTP2Flag));
WinHttpSetOption(hSession, WINHTTP_OPTION_DECOMPRESSION,
(LPVOID)&decompression, sizeof(decompression));
WinHttpSetStatusCallback(hSession, WinhttpStatusCallback,
WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, 0);
HINTERNET hConnect = WinHttpConnect(hSession,
L"example.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
尽管只调用了一次WinHttpConnect
,但使用WinHttpOpenRequest
发出多个请求会导致WinHTTP 在内部打开到目标服务器的新连接,这表明很遗憾没有实现多路复用。
【讨论】:
以上是关于WinHTTP over HTTP/2 多路复用的主要内容,如果未能解决你的问题,请参考以下文章
你能用.Net Core HttpClient实现Http/2多路复用吗?