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

使用Let's Encrypt证书时Socket.io无法连接的解决求助

Socket.io连接HTTPS服务器无报错断开的解决方法

我使用Let's Encrypt生成的证书搭建了HTTPS服务器,现在想要让Socket.io客户端连接附着在该HTTPS服务器上的Socket.io服务器,但Socket无报错直接断开连接。以下是我的代码:

服务端代码

const options = envResolver.isLocal ? {} : {
  key: fs.readFileSync(path.join(__dirname, "../cert/key.pem")),
  cert: fs.readFileSync(path.join(__dirname, "../cert/cert.pem")),
  rejectUnauthorized: false
}

const server = envResolver.isLocal ? http.createServer(app) : https.createServer(options, app)

const io = new Server(httpServer,  {
     pingInterval: 2000,
     pingTimeout: 5000
})

server.listen(process.env.PORT, () => {
  process.send && process.send("ready")
  winston.info(
    `Express app named ${serverName} started on port ${process.env.PORT} with env ${process.env.NODE_ENV}`
  )
})

客户端代码

const certPem = `-----BEGIN CERTIFICATE-----
server crt file string
    -----END CERTIFICATE-----
    `
this.socket = io('wss://<url>:3004', {
      transports: ['websocket'],
      query: this.apiHeader,
      ca: certPem.toString(),
      rejectUnauthorized: false,
      secure: true
});

目前我暂时将服务器的cert.pem文件存储在模板字符串中,后续会考虑如何加载证书文件。请问这种情况下如何让Socket.io成功连接?


问题修复方案

1. 服务端初始化变量错误

Socket.io初始化时引用了未定义的httpServer,必须替换为实际创建的server变量:

// 错误写法
const io = new Server(httpServer, { ... })

// 正确写法
const io = new Server(server, {
  pingInterval: 2000,
  pingTimeout: 5000
})

2. 移除服务端冗余配置

rejectUnauthorized是客户端的SSL验证选项,服务端配置中不需要该参数,直接删除:

const options = envResolver.isLocal ? {} : {
  key: fs.readFileSync(path.join(__dirname, "../cert/key.pem")),
  cert: fs.readFileSync(path.join(__dirname, "../cert/cert.pem"))
}

3. 简化客户端连接配置

  • Socket.io支持直接使用HTTPS地址,无需手动指定wss://,协议会自动适配
  • 已设置rejectUnauthorized: false时,无需手动传入CA证书(仅在强制验证自定义证书链时需要)
  • secure: true在HTTPS环境下是默认值,可省略

修复后的客户端代码:

this.socket = io('https://<url>:3004', {
  transports: ['websocket'],
  query: this.apiHeader,
  rejectUnauthorized: false
});

4. 额外排查要点

  • 确认服务器端口3004已对外开放,防火墙/安全组未拦截WebSocket流量
  • 验证服务端证书文件路径是否正确,可通过console.log(path.join(__dirname, "../cert/key.pem"))打印路径确认
  • 打开浏览器控制台Network标签,查看WebSocket连接请求的状态码和响应信息,排查隐藏错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:31:00