.NET WebSocket能接收消息但无法向客户端发送消息的问题排查
.NET Core WebSocket无法向Next.js客户端发送消息的排查与解决
问题场景
我有一个.NET Core应用,前端使用Next.js实现WebSocket客户端。目前能成功连接到后端,客户端发送的消息后端控制台可以接收,但后端返回的消息客户端无法收到。
.NET Core后端代码
var builder = WebApplication.CreateBuilder(args); IConfiguration configuration = builder.Configuration; builder.Services.AddCors(); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.UseWebSockets(); app.UseMiddleware<WebSocketMiddleware>(); app.Run(); public class WebSocketMiddleware(RequestDelegate next) { private readonly RequestDelegate _next = next; public async Task Invoke(HttpContext context) { if (context.WebSockets.IsWebSocketRequest) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); await HandleWebSocket(webSocket); } else { await _next(context); } } private static async Task HandleWebSocket(WebSocket webSocket) { try { byte[] buffer = new byte[1024]; WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); while (!result.CloseStatus.HasValue) { string message = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"Received message: {message}"); // Echo the message back to the client await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); // Array.Clear(buffer, 0, buffer.Length); result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); } catch (Exception ex) { Console.WriteLine($"WebSocket error: {ex.Message}"); } finally { webSocket.Dispose(); } } }
Next.js前端代码
import { useEffect, useState } from "react"; export default function Home() { const [input, setInput] = useState(""); const [messages, setMessage] = useState<string[]>([]); const socket = new WebSocket("ws://localhost:5114"); useEffect(() => { socket.onopen = function (event) { console.log("Connected to WebSocket server"); }; socket.onmessage = function (event) { console.log("Received message:", event.data); setMessage((oldArray) => [...oldArray, event.data]); }; socket.onclose = function (event) { console.log("WebSocket connection closed"); }; }, []); const onChangeHandler = (event: any) => { setInput(event.target.value); }; return ( <div style={{ display: "flex", flexDirection: "column" }}> <input type="text" onChange={onChangeHandler} value={input} /> <button onClick={() => { console.log("here"); // socket.emit("messageFromClient", { data: input }); socket.send(input); }}> Submit </button> {messages.map((item, index) => { return <h5 key={`${index}`}>{item}</h5>; })} </div> ); }
问题原因与解决方法
1. CORS配置缺失
虽然注册了CORS服务,但未启用CORS中间件。浏览器WebSocket连接受CORS规则约束,未正确配置会导致消息被拦截。
解决:
在app.UseWebSockets()前添加CORS配置,允许前端源:
app.UseCors(options => { options.WithOrigins("http://localhost:3000") // 替换为你的Next.js运行地址 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // WebSocket需要启用凭证支持 });
2. 中间件顺序错误
中间件执行顺序会影响请求处理,需确保CORS、WebSocket、自定义中间件的顺序正确:
app.UseCors(...); // 先处理CORS app.UseWebSockets(); // 再启用WebSocket支持 app.UseMiddleware<WebSocketMiddleware>(); // 最后使用自定义WebSocket中间件
3. 缓冲区未清空(可选优化)
循环接收消息时,缓冲区可能残留上一次数据,导致返回消息包含脏内容。取消注释缓冲区清空代码:
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); Array.Clear(buffer, 0, buffer.Length); // 恢复此行代码 result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
内容的提问来源于stack exchange,提问作者BraveEvidence
相关产品推荐
相关产品推荐

