.NET 8下System.Net.WebSockets无法持续接收消息问题咨询
.NET 8 WebSocket ReceiveAsync 无法持续接收后续消息问题
我在使用.NET 8的System.Net.WebSockets编写程序时遇到异常情况:客户端发送的第一条消息能被服务端成功接收,但后续发送的消息无法让ReceiveAsync持续返回。
以下是无法正常运行的简化示例代码:
[ApiController] [Route("[controller]")] public class WebSocketController : ControllerBase { [HttpGet] public async Task Get() { if (HttpContext.WebSockets.IsWebSocketRequest) { using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); await ReceiveMessages(webSocket); } else { HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; } } private static async Task ReceiveMessages(WebSocket webSocket) { WebSocketReceiveResult receiveResult; var buffer = new byte[1]; do { receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } while (!receiveResult.CloseStatus.HasValue); await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None); } }
但如果在每次接收消息后添加向客户端发送消息的代码,服务端就能正常接收所有客户端消息:
private static async Task ReceiveMessages(WebSocket webSocket) { WebSocketReceiveResult receiveResult; var buffer = new byte[1]; do { receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None); } while (!receiveResult.CloseStatus.HasValue); await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None); }
我的使用场景不需要每次接收消息都回复客户端。查阅RFC 6455和微软官方文档后,我认为第一段代码应该可以正常运行。请问我是对WebSocket或System.Net.WebSockets存在理解误区,还是该组件存在bug?
补充:以下是我的Program.cs代码,仅在默认ASP.NET Core Web API模板基础上添加了WebSocketMiddleware的使用:
public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.UseWebSockets(); app.MapControllers(); app.Run(); } }
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

