You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何创建集成API且可监听记录所有API调用的HTTP服务器

问题根因

你现有代码无法运行的核心原因是两个独立HTTP监听器同时尝试绑定8080端口:自定义的HttpServer(底层基于HttpListener实现)和后续启动的HttpSelfHostServer属于完全独立的监听实例,操作系统默认不允许多个实例无特殊配置时独占监听同一端口,启动时必然抛出端口占用异常。

完全不需要拆分两个独立服务,也不用单独启动HttpListener做请求监听,直接复用ASP.NET Web API SelfHost的原生请求管道做日志埋点即可,天然规避端口冲突,还能拿到完整的请求、响应数据。

正确实现方案

第一步:实现全局日志拦截处理器

自定义消息处理器继承DelegatingHandler,所有经过HTTP服务的请求、响应都会先经过这个处理器,在这里完成全量日志记录即可,不需要额外启动监听服务:

public class RequestLoggingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken)
    {
        // 记录请求基础信息:路径、方法、请求头、请求时间、客户端IP
        var requestInfo = new 
        {
            Path = request.RequestUri.AbsolutePath,
            Method = request.Method.Method,
            Headers = request.Headers.ToDictionary(h => h.Key, h => string.Join(";", h.Value)),
            RequestTime = DateTime.Now,
            ClientIP = request.GetOwinContext().Request.RemoteIpAddress
        };
        // 此处可按需将请求日志写入文件、数据库或做其他处理
        Log.Info($"收到请求: {JsonConvert.SerializeObject(requestInfo)}");

        // 将请求传递到后续管道,执行实际API业务逻辑
        var response = await base.SendAsync(request, cancellationToken);

        // 记录响应信息:状态码、处理耗时、响应内容
        var responseInfo = new 
        {
            StatusCode = (int)response.StatusCode,
            CostMs = (DateTime.Now - requestInfo.RequestTime).TotalMilliseconds,
            Content = await response.Content.ReadAsStringAsync(cancellationToken)
        };
        Log.Info($"请求处理完成: {JsonConvert.SerializeObject(responseInfo)}");

        return response;
    }
}

第二步:调整服务启动代码

删掉原有单独启动自定义HttpServer的逻辑,仅保留一个HttpSelfHostServer实例,将日志处理器注册到服务管道中:

static void Main(string[] args)
{
    Console.WriteLine("Starting HTTP server...");
    var config = new HttpSelfHostConfiguration("http://localhost:8080/");
    
    // 注册API路由
    config.Routes.MapHttpRoute(
        name: "API Default", 
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional });
    
    // 注册全局日志拦截器
    config.MessageHandlers.Add(new RequestLoggingHandler());

    using (HttpSelfHostServer server = new HttpSelfHostServer(config))
    {
        server.OpenAsync().Wait();
        Console.WriteLine("Server started at http://localhost:8080/, Press Enter to quit.");
        Console.ReadLine();
        server.CloseAsync().Wait();
    }

    Console.WriteLine("Exiting gracefully...");
}
方案适配性说明

该方案完全匹配你设计的Hub-Node分布式架构需求:

  • 正常对外提供API服务能力:所有/api/前缀的请求会正常路由到对应Controller处理,节点注册、心跳、任务日志上报等业务接口可正常开发使用
  • 全量通信日志无遗漏:所有发往Hub的请求,不管是Windows Node节点的调用还是其他外部API请求,都会被日志处理器拦截,可按需记录任意维度的通信数据
  • 彻底规避端口冲突:整个服务仅存在一个HTTP监听实例绑定指定端口,不存在多实例抢占端口的问题

注意事项:如果使用较老版本的Web API SelfHost,获取客户端IP需要先安装Microsoft.AspNet.WebApi.OwinSelfHost包,通过OWIN上下文读取;如果需要记录请求体内容,读取请求流后记得将流的Position重置为0,否则后续业务逻辑无法读取请求报文会报错。

内容的提问来源于stack exchange,提问作者Michał Cichoń

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:24:16