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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:04:55