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

SignalR Core连接因错误码1007异常断开,求排查解决

解决SignalR WebSocket错误1007(非UTF-8编码)的问题

我之前排查过几乎一模一样的问题,这个1007错误看起来是UTF-8编码问题,但根源其实是大字符串传输时的帧处理异常,尤其是包含大量多字节特殊字符(比如æøå,每个占2个UTF-8字节)的场景。咱们一步步拆解:

为什么你的强制编码没用?

先把那个forceUnicodeEncoding函数删掉——它反而会搞乱编码。JavaScript字符串本身就是UTF-16编码,SignalR会自动帮你转成标准UTF-8再发送。而unescape(encodeURIComponent(string))这套操作是过时的URI编码转义,会把UTF-8字节转成Latin-1字符,反而生成不符合规范的字符串,加重问题。

核心问题:大字符串的帧拆分截断

当你发送超长字符串时,WebSocket会把数据拆分成多个帧传输。如果某个多字节的UTF-8字符刚好被拆在两个帧的边界上,服务端解析时就会认为这是无效的UTF-8序列,直接触发1007错误关闭连接。少量特殊字符不会触发,是因为数据量小,不会被拆帧。

具体解决方案

1. 调整SignalR的消息大小限制(最直接)

默认情况下,SignalR的最大接收消息大小是32KB左右,当你的字符串超过这个阈值时,就容易出现帧拆分问题。在服务端和客户端都调整配置:

服务端(Program.cs/Startup.cs):

builder.Services.AddSignalR(options =>
{
    // 根据你的需求设置更大的阈值,比如1MB
    options.MaximumReceiveMessageSize = 1024 * 1024;
    // 开启详细错误,方便后续排查
    options.EnableDetailedErrors = true;
});

客户端:

const hubConnection = new signalR.HubConnectionBuilder()
    .withUrl("/yourHubEndpoint")
    .configureLogging(signalR.LogLevel.Information)
    .withAutomaticReconnect() // 加上自动重连,提升体验
    .build();

// 可以适当调整超时和心跳参数
hubConnection.serverTimeoutInMilliseconds = 30000;
hubConnection.keepAliveIntervalInMilliseconds = 15000;

2. 分块发送大内容(适合超大型文本)

如果你的文本内容经常超过1MB,可以把内容拆成小块发送,避免单帧过大:

客户端代码:

// 分块发送函数,chunkSize可根据需求调整
function sendContentInChunks(content, chunkSize = 1000) {
    for (let i = 0; i < content.length; i += chunkSize) {
        const chunk = content.slice(i, i + chunkSize);
        // 告诉服务端这是第一块、最后一块还是中间块
        hubConnection.invoke('SendContentChunk', chunk, i === 0, i + chunkSize >= content.length);
    }
}

// 替换原来的调用:
// this.hubConnection.invoke('SendContent', contentString);
sendContentInChunks(contentString);

Hub代码:

private static string _contentString = string.Empty;

public async Task SendContentChunk(string chunk, bool isFirst, bool isLast)
{
    // 第一块重置缓存,后续块拼接
    if (isFirst)
        _contentString = chunk;
    else
        _contentString += chunk;

    // 最后一块发送给其他用户
    if (isLast)
    {
        await Clients.Others.SendAsync("ReceiveContent", _contentString);
    }
}

3. 用二进制格式传输(最稳妥的编码保障)

直接把字符串转成UTF-8二进制数据发送,完全避免编码转换的歧义:

客户端代码:

// 字符串转UTF-8 ArrayBuffer
function stringToUtf8Buffer(str) {
    const encoder = new TextEncoder();
    return encoder.encode(str);
}

// 调用时传二进制数据
this.hubConnection.invoke('SendContentBinary', stringToUtf8Buffer(contentString));

Hub代码:

public async Task SendContentBinary(byte[] textBytes)
{
    _contentString = Encoding.UTF8.GetString(textBytes);
    await Clients.Others.SendAsync("ReceiveContent", _contentString);
}

验证步骤

  1. 删除你自己写的forceUnicodeEncoding函数;
  2. 先尝试调整消息大小限制,测试大量特殊字符的场景;
  3. 如果还出现问题,再试试分块或二进制传输的方案。

内容的提问来源于stack exchange,提问作者Simon Christiansen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:31:36