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

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

我有几个问题:

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

【问题讨论】:

    标签: c# multithreading concurrency dotnet-httpclient long-polling


    【解决方案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 进行检查。

        【讨论】:

          猜你喜欢
          • 2018-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多