如何在ASP.NET Core服务器上为无协议客户端默认context.WebSockets.WebSocketRequestedProtocols
解决ASP.NET Core WebSocket未传入子协议时的连接失败问题
当客户端未携带Sec-WebSocket-Protocol请求头时,ASP.NET Core的WebSocket中间件会因协议协商失败拒绝连接,你可以通过两种方式在服务器端配置默认子协议:
方式一:提前修改请求头(全局生效)
在WebSocket中间件前添加自定义中间件,检查请求头并补全默认协议:
// Program.cs 中配置中间件 app.Use(async (context, next) => { if (context.WebSockets.IsWebSocketRequest) { // 读取客户端请求的协议列表 var hasProtocolHeader = context.Request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var protocolValues); var requestedProtocols = hasProtocolHeader ? protocolValues.ToString().Split(',').Select(p => p.Trim()) : Enumerable.Empty<string>(); // 无请求协议时,添加默认协议到请求头 if (!requestedProtocols.Any()) { context.Request.Headers["Sec-WebSocket-Protocol"] = "desiredValue"; } } await next(); }); // 启用WebSocket中间件 app.UseWebSockets(); // 配置WebSocket端点 app.Map("/ws", async context => { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); // 可通过 webSocket.SubProtocol 获取最终协商的协议 // 后续通信逻辑... });
方式二:在接受连接时指定默认协议(端点级生效)
直接在AcceptWebSocketAsync方法中指定默认协议,无需修改请求头:
app.UseWebSockets(); app.Map("/ws", async context => { const string defaultProtocol = "desiredValue"; var requestedProtocols = context.WebSockets.WebSocketRequestedProtocols; // 优先使用客户端请求的协议,无则用默认值 var targetProtocol = requestedProtocols.Any() ? requestedProtocols.First() : defaultProtocol; using var webSocket = await context.WebSockets.AcceptWebSocketAsync(targetProtocol); // 通信逻辑... });
注意事项
- 默认协议名称需符合WebSocket规范,避免空格、特殊字符
- 如果客户端传入多个协议,可根据业务逻辑选择合适的协议(示例中取第一个)
- 测试时去掉Postman的
Sec-WebSocket-Protocol头,即可验证连接是否正常
内容的提问来源于stack exchange,提问作者artista_14
相关产品推荐
相关产品推荐

