讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

剧云
剧云

中文短剧剧本制作平台

Seko
Seko

AI短剧一键生成成片

updream

一键生成高质量推广成片

Fastify WebSocket 连接在 HTTPS 下失败的解决方案

轻墨酱_7804

轻墨酱_7804

发布时间:2026-02-18 14:06:13

|

327人浏览过

|

来源于php中文网

原创

Fastify WebSocket 连接在 HTTPS 下失败的解决方案

本文详解 fastify 配合 @fastify/websocket 在启用 https(即 wss)时连接失败的典型原因与完整解决路径,涵盖证书配置、服务端注册顺序、客户端连接方式及调试要点。

本文详解 fastify 配合 @fastify/websocket 在启用 https(即 wss)时连接失败的典型原因与完整解决路径,涵盖证书配置、服务端注册顺序、客户端连接方式及调试要点。

在使用 Fastify 构建全栈实时应用时,本地 HTTP 环境下 @fastify/websocket 通常能无缝工作;但一旦切换至 HTTPS(即需支持 wss:// 协议),前端 WebSocket 客户端常报错 ERR_CONNECTION_REFUSED 或 net::ERR_CERT_INVALID,而 Fastify 的 HTTPS 服务本身却正常响应 HTML/JSON —— 这表明问题不在于服务未启动,而在于 WSS 升级握手或 TLS 层配置存在隐性缺陷。

✅ 核心原因:WebSocket 依赖 HTTPS 实例的正确透传

@fastify/websocket 并非独立运行 WebSocket 服务器,而是复用 Fastify 底层 HTTP(S) Server 的 upgrade 事件。当启用 HTTPS 时,必须确保:

  • Fastify 实例显式以 HTTPS 模式初始化(而非先创建 HTTP 实例再“打补丁”);
  • @fastify/websocket 插件在 HTTPS 配置完成后再注册(注册顺序影响内部 server 引用);
  • 证书文件路径有效、权限可读,且私钥与证书匹配(常见错误:.key 与 .crt 不属同一对)。

你的原始代码中已基本满足前两点,但存在一个关键疏漏:未为 HTTPS 模式下的 fastify.listen() 显式指定 https: true 选项(尽管 Fastify 内部会识别,但部分 Node.js 版本或代理环境要求显式声明)。此外,客户端若仍尝试连接 ws://(而非 wss://),必然失败。

✅ 正确配置示例(含开发与生产适配)

const fs = require('fs');
const fastify = require('fastify');

const config = {
  privKey: process.env.PRIV_KEY || './certs/localhost-key.pem',
  certKey: process.env.CERT_KEY || './certs/localhost.pem',
  https: process.env.HTTPS === '1',
  domains: process.env.DOMAINS?.split(',') || ['http://localhost:3000'],
  port: parseInt(process.env.PORT) || 3000,
};

// ✅ 关键:统一构造 Fastify 实例,HTTPS 配置内聚
const fastifyInstance = fastify({
  serverTimeout: 60 * 60 * 1000,
  logger: true,
  ...(config.https && {
    https: {
      key: fs.readFileSync(config.privKey),
      cert: fs.readFileSync(config.certKey),
      // 可选:添加 ca 字段(如使用自签名中间 CA)
      // ca: fs.readFileSync('./certs/rootCA.pem'),
    }
  })
});

// ✅ 关键:CORS 需明确允许 wss:// 协议源(注意协议一致性)
fastifyInstance.register(require('@fastify/cors'), {
  origin: config.domains.map(domain => 
    domain.replace(/^http/, 'ws') // 将 http:// → ws://, https:// → wss://
  ),
  credentials: true
});

// ✅ 关键:WebSocket 插件必须在 HTTPS 配置后注册
fastifyInstance.register(require('@fastify/websocket'));

// WebSocket 路由定义
fastifyInstance.register(async function (instance) {
  instance.get('/live', { websocket: true }, (connection, request) => {
    console.log(`New WSS connection from ${request.socket.remoteAddress}`);

    connection.socket.on('message', (data) => {
      try {
        const msg = data.toString();
        console.log('Received:', msg);
        connection.socket.send(`Echo: ${msg}`);
      } catch (err) {
        console.error('Send error:', err);
      }
    });

    connection.socket.on('close', () => {
      console.log('Connection closed');
    });
  });
});

// ✅ 关键:listen 时无需额外传 https: true,但 host/port 必须显式
const start = async () => {
  try {
    const address = await fastifyInstance.listen({
      host: '0.0.0.0',
      port: config.port,
      // ⚠️ 注意:HTTPS 模式下,Node.js 原生 server 会自动处理 upgrade,
      // 无需手动设置 secureContext —— Fastify 已封装
    });
    fastifyInstance.log.info(`Server listening at ${address}`);
    if (config.https) {
      fastifyInstance.log.info(`WSS endpoint: wss://localhost:${config.port}/live`);
    } else {
      fastifyInstance.log.info(`WS endpoint: ws://localhost:${config.port}/live`);
    }
  } catch (err) {
    fastifyInstance.log.error(err);
    process.exit(1);
  }
};

start();

✅ 开发环境证书推荐方案:mkcert

正如答案所提示,自签名证书的兼容性是最大障碍。浏览器和现代 WebSocket 客户端(如 Chrome、Firefox、new WebSocket())默认拒绝不受信任的证书。解决方案:

  1. 安装 mkcert(官网):

    # macOS
    brew install mkcert nss
    mkcert -install
    
    # Windows (PowerShell as Admin)
    choco install mkcert
    mkcert -install
  2. 生成本地可信证书:

    WebSocket 8.18.2
    WebSocket 8.18.2

    WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。

    下载
    mkdir certs
    mkcert -key-file certs/localhost-key.pem -cert-file certs/localhost.pem "localhost"
  3. 设置环境变量启动:

    HTTPS=1 PRIV_KEY=./certs/localhost-key.pem CERT_KEY=./certs/localhost.pem PORT=3000 node server.js

此时 wss://localhost:3000/live 将被浏览器完全信任。

✅ 客户端连接注意事项

确保前端使用正确的协议与域名:

// ✅ 正确:协议与后端一致
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const socket = new WebSocket(`${protocol}//${window.location.host}/live`);

socket.onopen = () => console.log('WSS connected');
socket.onmessage = (e) => console.log('Server:', e.data);

若部署在 Nginx/Apache 后,还需配置反向代理透传 WebSocket 头(Upgrade, Connection),此非 Fastify 侧问题,但常被忽略。

✅ 总结:排查清单

检查项 是否满足 说明
✅ Fastify 实例初始化时已传入 https: { key, cert } ☐ 避免 HTTP 实例误用
✅ @fastify/websocket 在 HTTPS 配置后注册 ☐ 确保插件绑定到正确 server
✅ 证书文件路径正确、可读、配对无误 ☐ openssl x509 -in cert.pem -text -noout 验证
✅ 客户端使用 wss://(非 ws://)连接 HTTPS 服务 ☐ 协议必须严格匹配
✅ 开发环境使用 mkcert 生成的可信证书 ☐ 规避浏览器证书警告
✅ 防火墙放行端口,且无中间代理拦截 Upgrade 请求 ☐ curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" https://yoursite/live 测试

遵循以上结构化配置,即可稳定启用 Fastify 的 WSS 支持,兼顾开发效率与生产安全性。

热门AI工具

更多
创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
nginx 重启
nginx 重启

nginx重启对于网站的运维来说是非常重要的,根据不同的需求,可以选择简单重启、平滑重启或定时重启等方式。本专题为大家提供nginx重启的相关的文章、下载、课程内容,供大家免费下载体验。

423

2023.07.27

nginx 配置详解
nginx 配置详解

Nginx的配置是指设置和调整Nginx服务器的行为和功能的过程。通过配置文件,可以定义虚拟主机、HTTP请求处理、反向代理、缓存和负载均衡等功能。Nginx的配置语法简洁而强大,允许管理员根据自己的需要进行灵活的调整。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

4127

2023.08.04

nginx配置详解
nginx配置详解

NGINX与其他服务类似,因为它具有以特定格式编写的基于文本的配置文件。本专题为大家提供nginx配置相关的文章,大家可以免费学习。

6985

2023.08.04

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

601

2024.02.23

nginx报404怎么解决
nginx报404怎么解决

当访问 nginx 网页服务器时遇到 404 错误,表明服务器无法找到请求资源,可以通过以下步骤解决:1. 检查文件是否存在且路径正确;2. 检查文件权限并更改为 644 或 755;3. 检查 nginx 配置,确保根目录设置正确、没有冲突配置等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1516

2024.07.09

Nginx报404错误解决方法
Nginx报404错误解决方法

解决方法:只需要加上这段配置:try_files $uri $uri/ /index.html;即可。想了解更多Nginx的相关内容,可以阅读本专题下面的文章。

3998

2024.08.07

nginx部署php项目教程汇总
nginx部署php项目教程汇总

本专题整合了nginx部署php项目教程汇总,阅读专题下面的文章了解更多详细内容。

122

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

577

2026.01.13

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

40

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebSocket手册
WebSocket手册

共0课时 | 0人学习

Webman中文手册
Webman中文手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn