使用Httpclient进行长轮询

6

我正在使用 .Net 的 HttpClient 请求一个 REST API(GET)。我想使用长轮询 long polling 调用此 API。

我有几个问题:

  1. 使用长轮询检索数据的最佳方法是什么?
  2. 这是我的用例 - 我的应用程序将使用长轮询来消耗此API,根据结果,我将在不同的线程上执行一些操作。根据长轮询获取的新响应,我将中止/完成旧线程,并再次启动新线程进行操作。如何使用任务实现此目标?
3个回答

7

对于第一个问题,我找到了这个解决方案,它工作得相当好:

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());
    }
}

这是为客户端还是服务器端?如果这段代码不是为服务器端设计的,服务器如何将数据发送回客户端? - deathcat05
非常感谢你,兄弟!这对我今天真的帮了很大的忙。 :) - Treker
1
@Treker 没问题。我很惊讶这个五年前的答案仍然有效 :) - Denis Gordin
我也是如此坦白。我正在处理一个使用HTTP长轮询流式传输市场数据的财务API。它很棘手。供应商是TradeStation-https://api.tradestation.com/docs/fundamentals/http-streaming - Treker

1
我现在正在做这个。我有一个作为Windows服务运行的客户端。在启动时,服务将向Web服务器发送一个服务ID以进行识别。如果没有找到现有ID,则在启动时生成一个基本的GUID。
注册后,服务将在长轮询Web服务器资源上启动长轮询http请求。Web服务将呼叫者保留一段时间。如果未收到其他服务的唤醒调用,则会使用一个原因回答客户端请求。在处理响应后,客户端将立即启动新的长轮询请求。
Web服务还有一个WakeUp资源,用于其他服务向特定服务ID发出实际唤醒信号。长轮询和WakeUp功能共享要唤醒的服务ID列表。根据您的目标,可以根据解决方案的复杂性拥有多个唤醒原因。
Windows服务是多线程应用程序。一个普通的控制线程负责处理一般的Windows服务管理事项,并在服务控制管理器接收到OnStop事件时向工作线程发出信号。它还是设置其他所有内容的线程。会实例化其他工作线程并启动它们。

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

正如所说,您可以拥有多个不同的工作线程,执行不同的任务。移动文件、安装应用程序、删除非法应用程序、备份文件夹等等。天空真的是极限。

这基本上是我的系统的基本设计,它运行得非常好。它简单易用。


你有代码示例可以参考吗? - deathcat05
目前还不行。即使只是使用样板代码脚手架,像这样的项目仍然有很多工作要做。您可以通过创建一个带有LongPolling控制器的服务器项目,并具有一个简单的GET函数来开始,让ConsoleApp使用该GET函数。让函数挂起20秒钟,然后返回并使ConsoleApp执行另一个GET请求。这基本上是长轮询系统的开始。我会尝试制作一个非常基本的客户端/服务器系统,并发布到GitHub或类似的地方。 - Holm76

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接