C#和HttpListener在后台运行 [英] C# and running of HttpListener in background

查看:177
本文介绍了C#和HttpListener在后台运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的 HttpListener ,它侦听端口9090,并根据请求的URL向控制台写入一些信息.

但是我被困住了:(我想到了基于事件的多线程系统,但是我没办法做任何事情.

这是我作为单独的控制台应用程序启动的侦听器的代码:

  string urlTemplate = String.Format("/prefix/{0}/suffix",id);字符串前缀= String.Format("http://localhost:9090/");HttpListener监听器=新的HttpListener();listener.Prefixes.Add(prefix);listener.Start();Console.WriteLine(正在收听{0} ...",前缀);一会儿(true){HttpListenerContext context = listener.GetContext();HttpListenerRequest请求= context.Request;//响应对象HttpListenerResponse响应= context.Response;//构造响应如果(request.RawUrl.Contains(urlTemplate)&& request.HttpMethod =="POST"){字符串requestBody;流iStream = request.InputStream;编码编码= request.ContentEncoding;StreamReader reader =新的StreamReader(iStream,编码);requestBody = reader.ReadToEnd();Console.WriteLine(在正文= [{1}]的{0}上的POST请求",request.RawUrl,requestBody);response.StatusCode =(int)HttpStatusCode.OK;//返回响应使用(Stream stream = response.OutputStream){}}别的{response.StatusCode =(int)HttpStatusCode.BadRequest;Console.WriteLine(无效的HTTP请求:[{0}] {1}",request.HttpMethod,request.Url);使用(Stream stream = response.OutputStream){}}} 

我决定将其用作单元测试的实用程序(也许在其他地方).因此,在测试开始时,我需要配置侦听器,运行它,然后发出一些请求并接收信息(该侦听器先前已写入控制台),然后在测试结束时停止侦听器.

我的主要想法是将该侦听器封装到单独的类 MyHttpListener 中,该类具有方法: StartListener() StopListener().

但是当我调用 StartListener()时,由于无限的while循环,我的测试冻结了.我试图创建单独的后台线程或基于事件的系统,但是由于缺乏经验,我无法这样做.我已经花了很多时间试图找到解决方案,但是一无是处.

希望您能帮助我找到解决此类琐碎任务的方法.

谢谢.

解决方案

响应者的一种变体(似乎他删除了自己的帖子)看起来不错,但对我而言不起作用.我试图修复一些问题以使其开始起作用,但最后,该变体使我有了解决问题的想法-使用多线程和事件:)

这就是我现在拥有的并且可以正常工作:

 公共委托void HttpListenerRequestHandler(object sender,HttpListenerEventArgs e);公共事件HttpListenerRequestHandler OnCorrectRequest; 

...

  if(OnCorrectRequest!= null)OnCorrectRequest(this,new HttpListenerEventArgs(response));锁(threadLock){Console.WriteLine(在正文= [{1}]的{0}上的POST请求",request.RawUrl,requestBody);} 

...

 公共类HttpListenerEventArgs:EventArgs{公共只读HttpListenerResponse响应;公共HttpListenerEventArgs(HttpListenerResponse httpResponse){响应= httpResponse;}} 

为了从主线程中的HttpListener接收详细的响应,我使用以下内容:

  private HttpListenerResponse响应;公共无效HttpCallbackRequestCorrect(对象发送者,HttpListenerEventArgs e){响应= e.response;Console.WriteLine("{0}已发送:{1}",发件人,e.response.StatusCode);} 

不幸的是,我有以下异常,但我不知道如何处理:

System.Net.HttpListenerException:由于线程退出或应用程序请求,I/O操作已中止在System.Net.HttpListener.GetContext()

I created simple HttpListener that listens to port 9090 and depending on a request's URL writes some info to the console.

But I'm stuck :( I thought of multithreading, event based system, but I dind't manage to do anything with it.

Here is the code of my listener that I launched as a separate console app:

string urlTemplate = String.Format("/prefix/{0}/suffix", id);
string prefix = String.Format("http://localhost:9090/");

HttpListener listener = new HttpListener();
listener.Prefixes.Add(prefix);

listener.Start();

Console.WriteLine("Listening to {0}...", prefix);

while (true)
{
    HttpListenerContext context = listener.GetContext();
    HttpListenerRequest request = context.Request;

    //Response object
    HttpListenerResponse response = context.Response;

    //Construct response
    if (request.RawUrl.Contains(urlTemplate) && request.HttpMethod == "POST")
    {
         string requestBody;
         Stream iStream = request.InputStream;
         Encoding encoding = request.ContentEncoding;
         StreamReader reader = new StreamReader(iStream, encoding);
         requestBody = reader.ReadToEnd();

         Console.WriteLine("POST request on {0} with body = [{1}]", request.RawUrl, requestBody);

         response.StatusCode = (int)HttpStatusCode.OK;

         //Return a response
         using (Stream stream = response.OutputStream) { }
     }
     else
     {
         response.StatusCode = (int)HttpStatusCode.BadRequest;
         Console.WriteLine("Invalid HTTP request: [{0}] {1}", request.HttpMethod, request.Url);
         using (Stream stream = response.OutputStream) { }
     }
}

I decided to use it as an utility for unit tests (maybe somewhere else). So when test starts I need to configure the listener, run it, then make some requests and receive the info (which listener wrote earlier to Console), and at the end of the test stop the listener.

My main idea was to incapsulate this listener to separate class MyHttpListener which has methods: StartListener(), StopListener().

But when I call StartListener() my test freezes because of infinite while loop. I tried to create separate background thread or event based system, but my lack of experience with them, prevents me from doing it. I've already spent a lot of time trying to find the solution, but all for nothing.

Hope you can help me finding the solution for such trivial task.

Thanks in advance.

解决方案

One of the responder's variant (it seems he deleted his post) looked good, but it didn't work for me. I tried to fix things in order it started working, but at the end that variant gave me an idea how to solve the problem - with multithreading and events :)

Here's what I have now and it works:

public delegate void HttpListenerRequestHandler(object sender, HttpListenerEventArgs e);
public event HttpListenerRequestHandler OnCorrectRequest;

...

if(OnCorrectRequest != null)
    OnCorrectRequest(this, new HttpListenerEventArgs(response));
lock (threadLock)
{
    Console.WriteLine("POST request on {0} with body = [{1}]", request.RawUrl, requestBody);
}

...

public class HttpListenerEventArgs : EventArgs
{
    public readonly HttpListenerResponse response;
    public HttpListenerEventArgs(HttpListenerResponse httpResponse)
    {
        response = httpResponse;
    }
}

In order to receive detailed responses from HttpListener in main thread, I use the following:

private HttpListenerResponse response;

public void HttpCallbackRequestCorrect(object sender, HttpListenerEventArgs e)
{
    response = e.response;
    Console.WriteLine("{0} sent: {1}", sender, e.response.StatusCode);
}

Unfortunately I have the following exception which I don't know how to handle:

System.Net.HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request at System.Net.HttpListener.GetContext()

这篇关于C#和HttpListener在后台运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆