使用Httpclient进行长轮询

时间:2016-12-31 08:23:12

标签: c# multithreading concurrency dotnet-httpclient

我正在使用.net HttpClient使用一个REST API(GET)。我想用长轮询调用这个API。 我几乎没有问题:

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

3 个答案:

答案 0 :(得分: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());
    }
}

答案 1 :(得分:1)

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

注册后,服务将在长轮询Web服务器资源上启动长轮询http请求。 Web服务将在设定的时间量内驻留呼叫者。如果没有从其他服务接收到唤醒呼叫,则以某种原因回答客户请求。然后,客户端将在处理响应后立即开始新的长轮询请求。

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

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

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

如前所述,您可以有多个不同的工作线程来执行不同的操作。移动文件,安装应用程序,删除ilegal应用程序,制作文件夹备份。天空真的是极限。

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

答案 2 :(得分:0)

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进行检查。