.Net控制台WebSocket应用无法连接服务器问题求助
修复WebSocket服务端无法启动的问题
你的报错核心原因是服务端没有启动ASP.NET Core Web主机,同时代码里还有几处逻辑问题,下面是具体修复方案:
1. 补全服务端Main方法,启动Web主机
原来的Main方法是空的,ASP.NET Core应用必须构建并运行Web主机才能对外提供服务,修改后的Main方法如下:
public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Program>(); // 指定服务端监听端口,需和客户端连接地址保持一致 webBuilder.UseUrls("http://localhost:5000"); });
2. 调整中间件执行顺序
原来的中间件先调用await next.Invoke()再处理WebSocket请求,会导致请求先经过后续中间件(可能返回404),之后才处理WebSocket,逻辑顺序完全错误。修改后的Configure方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); var wsOptions = new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(120) }; app.UseWebSockets(wsOptions); // 先检查WebSocket请求,处理完成后不再执行后续中间件 app.Use(async (context, next) => { if (context.Request.Path == "/send") { if (context.WebSockets.IsWebSocketRequest) { using (WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync()) { await Send(context, webSocket); } return; } else { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } } // 非WebSocket请求,继续执行后续中间件 await next.Invoke(); }); }
3. 修复Send方法的潜在空引用问题
ReceiveAsync不会返回null,多余的null判断会导致后续关闭连接时出现空引用异常,修改后的Send方法:
private async Task Send(HttpContext context, WebSocket webSocket) { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); while (!result.CloseStatus.HasValue) { string msg = Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count)); Console.WriteLine($"client says: {msg}"); await webSocket.SendAsync( new ArraySegment<byte>(Encoding.UTF8.GetBytes($"Server says: {DateTime.UtcNow:f}")), result.MessageType, result.EndOfMessage, CancellationToken.None); result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); }
客户端注意事项
- 必须先启动服务端,再启动客户端
- 客户端连接的URI
ws://localhost:5000/send要和服务端配置的端口、路径完全一致
内容的提问来源于stack exchange,提问作者Hasan Ozan
相关产品推荐
相关产品推荐

