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

C#使用HttpListener搭建本地web服务器如何为不同前缀返回不同响应

C# HttpListener 多路径响应与刷新bug修复

原有代码核心问题

  • 执行顺序错误:先读取本地文件再获取请求上下文,返回内容永远是上一次请求时的旧数据
  • 多余上下文消费:ReloadPage方法额外调用HttpListener.GetContext()占用了下一次用户请求,直接导致需要刷新两次才能看到更新
  • 无路由匹配逻辑:未对请求路径做判断,所有访问前缀返回相同内容
  • 线程安全隐患:将HttpListenerContext设为静态全局变量,多请求场景下会出现资源冲突

修复后完整代码

1. 服务器启动逻辑

private static Thread responseThread;
// 全局静态HttpListener实例要先初始化
private static HttpListener HttpListener = new HttpListener();

public static void StartServer()
{
    Console.WriteLine("Starting server...");
    // 可以只加通用前缀,不需要逐个加路径前缀,后续通过路由判断即可
    HttpListener.Prefixes.Add("http://localhost:5000/");
    HttpListener.Start(); 
    Console.WriteLine("Server started, access http://localhost:5000 to view data");
    responseThread = new Thread(ResponseThread);
    responseThread.IsBackground = true; // 设为后台线程,程序退出时自动销毁
    responseThread.Start(); 
}

2. 请求响应与路由逻辑

private static void ResponseThread()
{
    const string jsonPath = @"C:\Users\Public\Documents\EchoStatsLogger\savedData.json";
    while (HttpListener.IsListening)
    {
        // 先获取请求上下文
        var context = HttpListener.GetContext();
        try
        {
            // 禁用浏览器缓存,避免返回旧内容
            context.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
            context.Response.Headers.Add("Pragma", "no-cache");
            context.Response.Headers.Add("Expires", "0");
            
            string responseContent = string.Empty;
            // 路由判断,根据不同路径返回不同内容
            switch (context.Request.Url.AbsolutePath.ToLower())
            {
                case "/home":
                    // 返回自定义主页HTML
                    responseContent = "<html><head><title>Home</title></head><body><h1>主页</h1><a href='/stats'>查看统计数据</a></body></html>";
                    context.Response.ContentType = "text/html; charset=utf-8";
                    break;
                case "/stats":
                    // 返回统计页面
                    var jsonData = File.ReadAllText(jsonPath);
                    responseContent = $"<html><head><title>Stats</title></head><body><h1>统计数据</h1><pre>{jsonData}</pre></body></html>";
                    context.Response.ContentType = "text/html; charset=utf-8";
                    break;
                default:
                    // 根路径直接返回json数据
                    responseContent = File.ReadAllText(jsonPath);
                    context.Response.ContentType = "application/json; charset=utf-8";
                    break;
            }

            var responseArray = Encoding.UTF8.GetBytes(responseContent);
            context.Response.OutputStream.Write(responseArray, 0, responseArray.Length);
            Console.WriteLine($"Request for {context.Request.Url.AbsolutePath} handled");
        }
        catch (Exception ex)
        {
            context.Response.StatusCode = 500;
            var errorBytes = Encoding.UTF8.GetBytes($"Server error: {ex.Message}");
            context.Response.OutputStream.Write(errorBytes, 0, errorBytes.Length);
        }
        finally
        {
            context.Response.KeepAlive = false;
            context.Response.Close();
        }
    }
}

修复说明

  1. 移除了逻辑错误的ReloadPage方法,不需要额外重定向即可实现每次刷新返回最新数据
  2. 调整执行顺序为「先拿请求→再读最新文件→返回内容」,从根源解决刷新两次才更新的问题
  3. 新增了路径路由逻辑,可根据需求扩展不同路径的返回内容
  4. 增加了缓存禁用响应头,避免浏览器缓存旧内容
  5. 增加了异常捕获逻辑,避免单请求出错导致整个服务崩溃

内容的提问来源于stack exchange,提问作者gr1ffin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:06:05