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

AspNetCore WebSocket无法发送Ping帧问题咨询

问题分析与解决方案

首先要明确:你遇到的问题并不是操作有误,而是ASP.NET Core 2.0版本的WebSocket中间件本身的限制——这个版本里的WebSocketOptions.KeepAliveInterval配置并不会自动让服务器发送Ping帧,这个自动发送Ping的功能是在ASP.NET Core 2.1及后续版本才被加入到官方中间件中的。

手动实现Ping帧发送(适配2.0版本)

既然你还在使用2.0版本,只能通过手动编写代码来定期发送Ping帧,具体步骤如下:

  1. 在WebSocket连接建立后,启动一个后台任务,按照你需要的间隔发送Ping帧。
  2. 使用WebSocket.SendAsync方法,指定消息类型为WebSocketMessageType.Ping。
  3. 同时可以监听客户端的Pong响应,确保连接状态正常。

这里给你一个适配官方示例的代码片段:

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
            var keepAliveToken = new CancellationTokenSource();
            
            // 启动后台Ping任务
            _ = Task.Run(async () =>
            {
                while (webSocket.State == WebSocketState.Open)
                {
                    try
                    {
                        var buffer = new ArraySegment<byte>(new byte[1]);
                        await webSocket.SendAsync(
                            buffer, 
                            WebSocketMessageType.Ping, 
                            endOfMessage: true, 
                            cancellationToken: keepAliveToken.Token);
                        await Task.Delay(TimeSpan.FromSeconds(1), keepAliveToken.Token);
                    }
                    catch
                    {
                        // 处理发送异常,比如连接已断开
                        break;
                    }
                }
            });

            // 处理客户端消息的原有逻辑
            var buffer = new byte[1024 * 4];
            WebSocketReceiveResult result;
            do
            {
                result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                // 这里可以判断是否是Pong帧
                if (result.MessageType == WebSocketMessageType.Pong)
                {
                    // 记录Pong响应,确认客户端存活
                    Console.WriteLine("Received Pong from client");
                }
                // 处理其他消息类型...
            } while (!result.CloseStatus.HasValue);

            // 取消Ping任务
            keepAliveToken.Cancel();
            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
        else
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
        }
    }
    else
    {
        await next();
    }
});

长期解决方案:升级ASP.NET Core版本

如果条件允许,建议你升级到ASP.NET Core 2.1或更高版本——在这些版本中,WebSocketOptions.KeepAliveInterval配置会自动生效,中间件会定期向客户端发送Ping帧,无需手动编写额外代码。升级后你当前的配置代码就能正常工作。

另外需要注意:Chrome开发者工具在监控WebSocket帧时,Ping/Pong帧可能会被归类在"Frames"面板的"Other"类型下,你可以仔细检查这个分类下的帧数据,确认是否收到Ping帧。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:15:20