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

C#编写本地端口拦截代理时WebSocket连接进入aborted状态求解

问题原因分析
  • 请求获取逻辑错误:FakeDevice方法仅在进入循环前调用了一次listener.GetContext(),后续循环一直在重复处理同一个请求上下文,没有处理新的连接请求。
  • async void滥用:FakeDevice和Process方法都用了async void返回值,这类方法仅适用于事件处理器,普通异步方法使用async void会导致调用方无法等待异步执行流程,异常也无法正常捕获,Main方法调用FakeDevice后没有等待逻辑,程序可能直接退出。
  • 连接建立后直接返回:第一次收到WebSocket请求、完成AcceptWebSocketAsync握手后,代码直接return,后续的收发逻辑完全没有执行,浏览器端连接因为长时间没有后续交互被强制中断。
  • 全局WebSocket上下文共享错误:将WebSocketContext设为静态全局变量,仅能处理单个连接,且新连接进来后会直接复用旧连接的上下文,逻辑完全不符合代理多连接处理要求。
  • 同步方法阻塞:使用同步的listener.GetContext()会阻塞线程,应该搭配异步方法GetContextAsync()使用。
修正后参考代码
class Program
{
    static async Task Main(string[] args)
    {
        await FakeDevice();
    }

    protected async static Task FakeDevice()
    {
        HttpListener listener = new HttpListener();
        listener.Prefixes.Add("http://localhost:4033/");
        listener.Start();
        Console.WriteLine("服务已启动,监听端口4033");
        while (listener.IsListening)
        {
            // 每次循环获取新的请求上下文
            var context = await listener.GetContextAsync();
            // 每个连接单独开异步处理,不阻塞后续请求接收
            _ = Process(context);
        }
    }

    protected async static Task Process(HttpListenerContext context)
    {
        if (context.Request.IsWebSocketRequest)
        {
            WebSocketContext wsContext = null;
            try
            {
                // 完成WebSocket握手
                wsContext = await context.AcceptWebSocketAsync(subProtocol: null);
                var socket = wsContext.WebSocket;
                byte[] receiveBuffer = new byte[1024];
                while (socket.State == WebSocketState.Open)
                {
                    WebSocketReceiveResult receiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
                    }
                    else
                    {
                        // 这里当前是回显逻辑,可后续修改为代理转发逻辑
                        await socket.SendAsync(new ArraySegment<byte>(receiveBuffer, 0, receiveResult.Count), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"连接处理异常: {e.Message}");
            }
            finally
            {
                wsContext?.WebSocket.Dispose();
            }
        }
        else
        {
            // 非WebSocket请求返回400
            context.Response.StatusCode = 400;
            context.Response.Close();
            Console.WriteLine("收到非WebSocket请求");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:27:03