HttpListener应用处理首个请求后关闭,如何实现永久处理请求?
解决HttpListener处理完第一个请求就关闭的问题
你的代码核心问题是:RunWebHookSubscription方法仅调用了一次GetContextAsync,处理完第一个请求后方法执行完毕,程序自然退出。要实现永久处理请求,需要循环监听请求,同时异步处理每个请求以避免阻塞主线程。
修改后的完整代码
await main.RunWebHookSubscription(); public async Task RunWebHookSubscription(CancellationToken cancellationToken = default) { Console.WriteLine("Hook waiting"); using HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://localhost:8080/hook/"); listener.Start(); try { // 循环监听请求,直到收到取消信号或程序终止 while (!cancellationToken.IsCancellationRequested) { // 异步获取请求上下文,不阻塞循环 HttpListenerContext context = await listener.GetContextAsync(); // 异步处理请求,单独捕获异常避免影响整个监听服务 _ = HandleRequestAsyncRun(context).ContinueWith(t => { if (t.Exception != null) { Console.WriteLine($"处理请求出错: {t.Exception.Message}"); } }, TaskContinuationOptions.OnlyOnFaulted); } } finally { listener.Stop(); Console.WriteLine("Hook已停止"); } } async Task HandleRequestAsyncRun(HttpListenerContext context) { try { var request = context.Request; var body = WebHookRequestHadler(request); Console.WriteLine(body); if (!string.IsNullOrEmpty(body)) { var eventData = JsonSerializer.Deserialize<WebHookEventData>(body); // TODO: 调用业务方法处理事件 } // 返回成功响应,避免客户端超时 var response = context.Response; response.StatusCode = 200; response.ContentType = "application/json"; using var writer = new StreamWriter(response.OutputStream); await writer.WriteAsync("{\"status\":\"success\"}"); response.Close(); } catch (Exception ex) { Console.WriteLine($"处理请求异常: {ex.ToString()}"); // 返回错误响应 var response = context.Response; response.StatusCode = 500; response.ContentType = "application/json"; using var writer = new StreamWriter(response.OutputStream); await writer.WriteAsync($"{{\"status\":\"error\",\"message\":\"{ex.Message}\"}}"); response.Close(); } } string WebHookRequestHadler(HttpListenerRequest request) { if (!request.HasEntityBody) { return null; } using System.IO.Stream body = request.InputStream; using var reader = new System.IO.StreamReader(body, request.ContentEncoding); return reader.ReadToEnd(); }
关键修改说明
- 循环监听:通过
while循环持续调用GetContextAsync,确保服务一直等待新请求。 - 异步处理请求:获取请求上下文后,异步执行处理逻辑,不阻塞下一次请求的监听,支持并发处理多个WebHook请求。
- 异常隔离:在请求处理方法和异步任务中单独捕获异常,避免单个请求的错误导致整个监听服务崩溃。
- 响应返回:补充了成功/错误响应的返回逻辑,符合WebHook规范,避免客户端长时间等待超时。
- 资源管理:用
using包裹HttpListener和流对象,确保资源能正确释放。
额外建议
- 若需要优雅关闭服务,可以通过
CancellationToken监听控制台终止信号(如Ctrl+C),触发循环退出。 - 建议替换
Console.WriteLine为专业日志框架(如Serilog、NLog),方便生产环境排查问题。 - 增加WebHook请求签名验证逻辑,确保请求来源合法,防止恶意请求。
内容的提问来源于stack exchange,提问作者Dmitry Sokolov
相关产品推荐
相关产品推荐

