使用 Httpclient 进行长轮询

Posted

技术标签:

【中文标题】使用 Httpclient 进行长轮询【英文标题】:Long polling with Httpclient 【发布时间】:2017-05-15 08:56:59 【问题描述】:

我正在使用 .Net HttpClient 使用一个 REST API (GET)。我想用long polling调用这个API。

我有几个问题:

    使用长轮询检索数据的最佳方法是什么? 这是我的用例 - 我的应用程序将通过长轮询来使用这个 api,并根据结果我将在不同的线程上执行一些操作。基于 long poll get 的新响应,我将中止/完成旧线程并再次在新线程上开始操作。如何使用 Tasks 实现这一点?

【问题讨论】:

【参考方案1】:

对于第一个问题,我找到了this 解决方案,效果很好:

var url = "http://your.url";
using (var client = new HttpClient())

    client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
    var request = new HttpRequestMessage(HttpMethod.Get, url);
    using (var response = await client.SendAsync(
        request, 
        HttpCompletionOption.ResponseHeadersRead))
    
        using (var body = await response.Content.ReadAsStreamAsync())
        using (var reader = new StreamReader(body))
            while (!reader.EndOfStream)
                Console.WriteLine(reader.ReadLine());
    

【讨论】:

【参考方案2】:

我目前正在这样做。我有一个作为 Windows 服务运行的客户端。在启动时,服务将向网络服务器发布一个 serviceID 以进行识别。如果没有找到现有的 ID,它基本上只是在启动时生成的 GUID。

注册后,服务将在长轮询 Web 服务器资源上启动长轮询 http 请求。 Web 服务将在设定的时间内停放呼叫者。如果没有从其他服务接收到唤醒呼叫,则客户端请求会得到答复并说明原因。客户端会在处理完响应后立即开始一个新的长轮询请求。

Web 服务还具有用于其他服务的 WakeUp 资源,以指示特定的 serviceID 应该接收实际的 WakeUp。 Longpolling 和 WakeUp 函数共享要唤醒的 serviceID 列表。根据您的目标,您可以有多种唤醒原因,具体取决于您的解决方案的复杂性。

Windows 服务被实现为多线程应用程序。如果服务从服务控制管理器接收到 OnStop 事件,则一个通用控制线程处理通用 Windows 服务管理内容并向工作线程发出信号。它也是设置所有其他事情的线程。实例化其他工作线程并启动它们。

LongPolling 线程,唯一的工作就是处理 longpolling 调用的结果。当收到响应时,它会检查结果并根据结果激活其他线程,然后启动新的长轮询请求。这意味着它能够在其他工作线程正在处理它们的任务时接收新任务。

如上所述,您可以有多个不同的工作线程来做不同的事情。移动文件、安装应用程序、删除非法应用程序、备份文件夹。天空真的是极限。

这几乎是我系统的基本设计,而且效果非常好。它简单易用。

【讨论】:

【参考方案3】:
var socketsHandler = new SocketsHttpHandler

      PooledConnectionIdleTimeout = TimeSpan.FromHours(27),//Actually 5 mins can be idle at maximum. Note that timeouts longer than the TCP timeout may be ignored if no keep-alive TCP message is set at the transport level.
      MaxConnectionsPerServer = 10
;
client = new HttpClient(socketsHandler);

如您所见,虽然我将空闲超时设置为 27 小时,但实际上它只保持 5 分钟。

所以,最后我只是每 1 分钟使用相同的 HttpClient 调用目标端点。在这种情况下,始终存在已建立的连接。您可以使用 netstat 进行检查。

【讨论】:

以上是关于使用 Httpclient 进行长轮询的主要内容,如果未能解决你的问题,请参考以下文章

使用 php curl 进行长轮询

Comet,使用 jquery 教程进行长轮询 [关闭]

使用 Node.js 和 ajax 进行长轮询

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

使用 EventMachine 的 Rails 应用程序是不是可以进行长轮询?

在带有 turbolink 的 Rails 中使用 jQuery 进行长轮询