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

升级Node.js至18.0.0后HTTPS环境下SignalR连接失败求助

Node.js 18+ 连接 .NET 8 SignalR HTTPS 失败问题解决办法

客户端代码

index.js

const signalR = require("@microsoft/signalr");

// 禁用TLS验证即可正常运行
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; 

let connection = new signalR.HubConnectionBuilder()
      .withUrl("https://myapp.mydomain.com:5000/messageHub",
     // .withUrl("http://myapp.mydomain.com:5002/messageHub", // 使用HTTP时可正常运行
    {
         withCredentials: false
    })
    .withAutomaticReconnect()
    .configureLogging(signalR.LogLevel.Information)
    .build();
    connection.logging = true;
    async function start() {
    try {
        await connection.start({ withCredentials: false });
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

connection.onclose(async () => {
    await start();
});

start();

package.json

{
  "name": "Client",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@microsoft/signalr": "8.0.0"
  }
}

相关现象

  • Node.js 17.9.1及更早版本运行正常,升级至18.0.0及之后版本连接失败
  • 使用HTTP而非HTTPS时可正常运行
  • 禁用TLS验证(设置process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;)能运行,但不希望采用该方式

错误信息

[2024-02-08T11:06:44.246Z] Error: Failed to complete negotiation with the server: TypeError: fetch failed
[2024-02-08T11:06:44.246Z] Error: Failed to start the connection: Error: Failed to complete negotiation with the server: TypeError: fetch failed
FailedToNegotiateWithServerError: Failed to complete negotiation with the server: TypeError: fetch failed
    at HttpConnection._getNegotiationResponse (C:\dev\20240227electron\node_modules\@microsoft\signalr\dist\cjs\HttpConnection.js:257:35)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async HttpConnection._startInternal (C:\dev\20240227electron\node_modules\@microsoft\signalr\dist\cjs\HttpConnection.js:170:41)
    at async HttpConnection.start (C:\dev\20240227electron\node_modules\@microsoft\signalr\dist\cjs\HttpConnection.js:73:9)
    at async HubConnection._startInternal (C:\dev\20240227electron\node_modules\@microsoft\signalr\dist\cjs\HubConnection.js:135:9)
    at async HubConnection._startWithStateTransitions (C:\dev\20240227electron\node_modules\@microsoft\signalr\dist\cjs\HubConnection.js:112:13)
    at async Timeout.start [as _onTimeout] (C:\dev\20240227electron\index.js:18:9) {

解决办法

1. 指定可信CA证书

Node.js 18+ 默认启用更严格的TLS证书验证逻辑,如果服务器使用自签名证书或内部CA颁发的证书,需在连接配置中显式指定CA证书:

const signalR = require("@microsoft/signalr");
const fs = require('fs');
const https = require('https');

let connection = new signalR.HubConnectionBuilder()
      .withUrl("https://myapp.mydomain.com:5000/messageHub", {
         withCredentials: false,
         httpsAgent: new https.Agent({
             ca: fs.readFileSync('/path/to/your/ca-certificate.pem')
         })
      })
      .withAutomaticReconnect()
      .configureLogging(signalR.LogLevel.Information)
      .build();

替换/path/to/your/ca-certificate.pem为实际的CA证书文件路径。

2. 检查服务器TLS协议版本

Node.js 18+ 移除了对TLS 1.0、TLS 1.1的支持,确保服务器配置使用TLS 1.2或更高版本。可通过以下命令验证服务器TLS配置:

openssl s_client -connect myapp.mydomain.com:5000

3. 确保证书链完整

服务器需正确配置完整的证书链(包含根证书、中间证书),Node.js 18+ 对证书链完整性的验证更严格,缺失中间证书会导致验证失败。

4. 通过fetch选项传递TLS配置

如果SignalR客户端使用fetch API发起请求,可通过fetchOptions传递TLS代理配置:

.withUrl("https://myapp.mydomain.com:5000/messageHub", {
    withCredentials: false,
    fetchOptions: {
        agent: new https.Agent({
            ca: fs.readFileSync('/path/to/ca-certificate.pem')
        })
    }
})

内容的提问来源于stack exchange,提问作者George Vovos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:45:56