【问题标题】:How to create a HTTP request listener Windows Service in .NET如何在 .NET 中创建 HTTP 请求侦听器 Windows 服务
【发布时间】:2010-10-14 08:56:35
【问题描述】:

我想创建充当 HTTP 侦听器并可以处理大约 500 个客户端的 Windows 服务。这种服务有什么特别的考虑吗?

我对 HTTPListener 类和 TCPListener 类有点困惑。哪一个用于 Windows 服务:

  1. 接受客户端连接(500左右)
  2. 处理客户端请求
  3. 调用另一个基于 Http 的服务
  4. 向调用客户端返回一些值

这就是我正在做的启动监听器。

    listener = new HttpListener();
    listener.Prefixes.Add("http://localhost:8080/");
    listener.Start();
    listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);

private void OnRequestReceive(IAsyncResult result)
{
     HttpListener listener = (HttpListener)result.AsyncState;
     // Call EndGetContext to complete the asynchronous operation.
     HttpListenerContext context = listener.EndGetContext(result);
     HttpListenerRequest request = context.Request;
} 

我能同时处理 N 个客户吗?

【问题讨论】:

    标签: http service tcp


    【解决方案1】:

    如果您需要能够高度响应 HttpListener 将无法很好地扩展(您一次不能接受多个连接)。但是对于小规模使用,小心获取上下文并异步写入响应是可以工作的。

    编辑:似乎我误解了HttpListener 接受连接的能力。您可以同时接受多个连接(见评论)。然而,IIS 的其他托管代码设施将避免重新发明轮子。因此,除非有非常具体的要求排除 IIS,否则为什么不走捷径呢?

    如果要认真使用,请使用 IIS,创建一个 Http Handler(实现 IHttpHandler 或 IHttpHandlerFactory,甚至是 IHttpAsyncHandler 的类)来处理请求(这是实现 .aspx 等的底层类型)。

    正确的解决方案实际上取决于您所说的“处理大约 500 个客户”是什么意思:一次一个或一次?

    根据评论回答:500 一次,并注意到第 3 步中的处理包括另一个 HTTP 调用,我怀疑使用 HttpListner 是否能够在不确保每个操作都是异步的情况下处理负载(获取上下文和请求,执行向前的 HTTP 请求,然后发送响应)...这将导致一些更困难的编码。

    除非有充分的理由避免使用 IIS,否则使用 IIS 会更容易,因为它旨在支持具有丰富功能的大规模客户端请求负载,而 HttpListener “提供简单的、以编程方式控制的 HTTP 协议侦听器。”。

    编辑:根据负载的更多细节进行扩展。

    【讨论】:

    • 我的意思是在任何给定时间都可以有 1-500 个客户端连接到该服务。而且,每个客户端的处理时间都会很短。
    • 您能否提供一些声称 HttpListener 一次不能接受多个连接的来源?我正在运行使用 HttpListener 的代码,在我看来它正在同时处理多个请求。通过多次调用 BeginGetContext,您可以有效地设置多个侦听器。此外,HttpListener 基于 http.sys,与 IIS 用于服务请求的方式相同,因此性能应该相当。
    【解决方案2】:

    我会使用HttpListener 类。它为你做了很多事情,你不需要重新发明轮子。它还与 Windows Server 2003 中的内核模式 http.sys 驱动程序集成,应该会提供更好的性能。

    【讨论】:

      【解决方案3】:

      我创建了一个 TcpListener 并使用 BeginAcceptTcpClient 方法启动了监听器。每个传入请求都被带到一个单独的线程进行处理,其中客户端连接被连续用于从客户端获取/发送数据。 它似乎适用于大量客户。

      【讨论】:

        【解决方案4】:

        BeginGetContext 只接受一个请求。您需要在每次收到请求时重复异步调用,以便处理多个请求。

        有些人通过在循环中同步等待(即使用同步 GetContext)的侦听器线程来简化他们的设计。这不是一个好的设计,因为您最终会让一个线程坐在那里等待(浪费系统资源),但如果您对性能/概念验证实施不感兴趣,它可能是可以接受的。

        您还需要在服务关闭方法中调用 listener.Close()。小心将此与可能的异步线程处理请求同步。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-26
          • 2010-10-28
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-30
          相关资源
          最近更新 更多