如何为WinHttpWebSocketReceive同步调用设置接收超时?
如何为WinHttpWebSocketReceive同步调用设置接收超时
WinHttpSetTimeouts确实无法作用于WinHttpWebSocketReceive,因为WebSocket相关API属于独立的协议交互通道,不继承普通HTTP请求的超时配置。以下是两种可行的解决方案:
推荐方案:重叠IO+事件等待实现超时控制
通过异步调用WinHttpWebSocketReceive,配合事件对象的超时等待来模拟同步调用的超时效果,这是最安全的实现方式:HANDLE hWaitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); OVERLAPPED overlapped = {0}; overlapped.hEvent = hWaitEvent; DWORD recvBytes = 0; WINHTTP_WEB_SOCKET_BUFFER recvBuffer = { .BufferType = WINHTTP_WEB_SOCKET_BINARY_BUFFER_TYPE, .Buffer = your_recv_buffer, .BufferLength = your_buffer_size }; WINHTTP_WEB_SOCKET_RESULT recvResult; // 发起异步接收请求 BOOL callResult = WinHttpWebSocketReceive(hWebSocketHandle, &recvBuffer, 1, &recvBytes, &overlapped); if (!callResult && GetLastError() == ERROR_IO_PENDING) { // 设置超时时间(示例为5000毫秒) DWORD waitStatus = WaitForSingleObject(hWaitEvent, 5000); if (waitStatus == WAIT_TIMEOUT) { // 触发超时逻辑,可主动关闭WebSocket连接 WinHttpWebSocketClose(hWebSocketHandle, WINHTTP_WEB_SOCKET_ABORTED_CLOSE_STATUS, NULL, 0); } else if (waitStatus == WAIT_OBJECT_0) { // 接收完成,获取最终结果 if (!WinHttpWebSocketGetResult(hWebSocketHandle, &overlapped, &recvBytes, &recvResult)) { // 处理接收错误 } } } CloseHandle(hWaitEvent);不推荐方案:线程封装+强制终止
将WinHttpWebSocketReceive放入独立线程执行,主线程通过WaitForSingleObject等待线程结束,超时则调用TerminateThread终止子线程。但这种方式可能导致WinHTTP内部资源泄漏、状态异常,仅作为极端场景的临时方案。
核心原因:WinHttpSetTimeouts仅配置普通HTTP请求(如WinHttpSendRequest、WinHttpReceiveResponse)的连接、发送、接收超时,WebSocket是HTTP升级后的独立会话,其API不共享这些超时规则。
内容的提问来源于stack exchange,提问作者Stijn Sanders
相关产品推荐
相关产品推荐

