c - 使用 WinAPI 的 InternetReadFile() 进行长轮询

标签 c http winapi long-polling wininet

我正在编写一个跨平台应用程序。我需要从长轮询网址获取数据。

在 Mac/Linux 上我可以使用curl,curl_easy_perform()会自动处理所有事情。

在 Windows 上我必须使用 native api。下面的代码对于普通 url 工作正常,但是当我尝试使用 longpoll url 时,它会立即退出 (nr_read == 0),而不是等到有新数据为止:

...
   flags =
 INTERNET_FLAG_HYPERLINK | INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
 INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
 INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
 INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_NO_AUTH |
 INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI |
 INTERNET_FLAG_NO_COOKIES  |  
 INTERNET_FLAG_KEEP_CONNECTION |
 INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD 
 INTERNET_FLAG_SECURE;
...

HINTERNET internet = InternetOpenA(user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET connect = InternetConnectA(internet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
HINTERNET request = HttpOpenRequest(connect, req_typ, path, "HTTP/1.1", NULL, NULL, flags, NULL);


#define BUF_MAX 1024
TCHAR buf[BUF_MAX + 1];
int nr_read = 0;
while (1) {
     int ok = InternetReadFile(request, buf, BUF_MAX, &nr_read);
     if (!ok) {
             puts("not ok");
             break;
     }
     if (nr_read == 0) {
             puts("nr read 0, breaking");
             break;
     }
     buf[nr_read] = 0;
     printf("buf='%s'\n", buf);
     nr_read = 0;
}

我收到的响应 header :

HTTP/1.1 101
Switching Protocols
upgrade: websocket
connection: upgrade

握手后,libcurl 继续管道 websocket 数据(我可以手动处理),但 InternetReadFile() 只是退出。

我使用

发送 http 请求
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: key
Sec-WebSocket-Version: 13

服务器使用上面的 header 进行应答,然后 libcurl 给我 {"type": "hello"} 等等,但 InternetReadFile() 只是退出。

最佳答案

我最终使用了 libcurl :)

..

关于c - 使用 WinAPI 的 InternetReadFile() 进行长轮询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56279957/

相关文章:

c# - WCF Rest 服务 - 获取对 HTTP 响应 header 的访问权限

http - CORS 预检请求的正确状态代码是什么?

python - 如何删除我在他人计算机上设置的 cookie?

c++ - Win32编程 TextOut WM_Paint

c - 我无法使用 malloc() 和 realloc() 函数分配内存

c - 如何让我的机器人沿着黑色胶带沿着矩形路径移动?

delphi - TFileStream.Seek 超出文件末尾

c - GetThreadTimes 如何报告休眠时间?

c - 如何退出简单的生产者-消费者问题

在 while 循环中使用 scanf() 检查输入类型