讲师中心 微信公众号

工具推荐

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

低成本歌曲 MV、视频生成

Laper
Laper

剧本策划到成片协作

Seko
Seko

AI短剧一键生成成片

AniShort
AniShort

AI短剧协同制作平台

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

落丽吖_9378

落丽吖_9378

发布时间:2026-02-18 09:45:02

|

345人浏览过

|

来源于php中文网

原创

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

本文详解 fastify 配合 @fastify/websocket 在启用 https(wss)时连接失败的常见原因与实战修复方案,涵盖证书配置、服务器初始化逻辑、客户端连接注意事项及调试技巧。

本文详解 fastify 配合 @fastify/websocket 在启用 https(wss)时连接失败的常见原因与实战修复方案,涵盖证书配置、服务器初始化逻辑、客户端连接注意事项及调试技巧。

在使用 Fastify 构建全栈实时应用时,@fastify/websocket 是官方推荐的 WebSocket 插件,但许多开发者在从 HTTP 切换到 HTTPS 后会遇到 ws:// 可连而 wss:// 无法建立连接的问题——服务端日志无报错、HTTPS 页面正常加载,但浏览器控制台提示 net::ERR_CONNECTION_REFUSED 或 Error during WebSocket handshake: net::ERR_SSL_PROTOCOL_ERROR。这并非插件兼容性问题,而是 HTTPS/WSS 协议协同中的典型配置疏漏。

✅ 正确初始化 Fastify 实例(关键!)

首要问题是:WebSocket 支持必须与 HTTPS 配置同步注入 Fastify 实例。你当前的代码中,@fastify/websocket 是在 https: {...} 选项外注册的,看似无害,但 Fastify 的 WebSocket 插件依赖底层 server 实例的协议能力。若 https 配置未在 fastify() 构造时传入,即使后续监听 HTTPS 端口,WebSocket 升级(upgrade)请求仍可能被降级处理或拒绝。

请统一使用以下初始化方式(推荐单实例 + 条件化配置):

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

const config = {
  privKey: process.env.PRIV_KEY,
  certKey: process.env.CERT_KEY,
  https: process.env.HTTPS === '1',
  domains: process.env.DOMAINS?.split(',') || ['*'],
  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: fs.readFileSync('./fullchain.pem'),
    }
  })
});

// ✅ 此时再注册 CORS 和 WebSocket(顺序无关紧要,但必须在 listen() 前)
fastifyInstance.register(require('@fastify/cors'), {
  origin: config.domains,
});

fastifyInstance.register(require('@fastify/websocket'));

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

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

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

// 启动监听(自动适配 http(s))
const start = async () => {
  try {
    const address = await fastifyInstance.listen({
      host: '0.0.0.0',
      port: config.port,
      // ⚠️ 重要:HTTPS 模式下必须显式指定 secure: true(否则默认走 HTTP)
      ...(config.https && { secure: true })
    });
    fastifyInstance.log.info(`Server listening at ${address}`);
  } catch (err) {
    fastifyInstance.log.error(err);
    process.exit(1);
  }
};

start();

? 证书要求:WSS 不接受自签名证书(除非显式信任)

你提到“证书有效,Fastify HTTPS 工作正常”,但需注意:浏览器对 wss:// 的 TLS 校验比 https:// 更严格。即使页面通过 https:// 加载,WebSocket 连接仍会独立校验证书链完整性。

  • ❌ 浏览器直接拒绝未受信的自签名证书(如 OpenSSL 生成的),且不会弹出“继续访问”提示;

  • ✅ 推荐开发环境使用 mkcert 生成本地可信证书:

    # 安装并初始化本地 CA
    mkcert -install
    # 为 localhost 生成证书
    mkcert localhost 127.0.0.1 ::1
    # 输出:localhost-key.pem + localhost.pem

    将生成的 .pem 文件路径赋给 PRIV_KEY 和 CERT_KEY 环境变量即可。

    WebSocket 8.18.2
    WebSocket 8.18.2

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

    下载
  • ? 生产环境务必使用 Let’s Encrypt(certbot)或云厂商签发的完整证书链(含 fullchain.pem),避免因缺少中间证书导致 WSS 握手失败。

? 客户端连接:协议必须严格匹配

前端连接时,务必确保 URL 协议与服务端一致:

// ✅ 正确:HTTPS 页面 → WSS 连接
const ws = new WebSocket('wss://your-domain.com/live');

// ❌ 错误:HTTPS 页面尝试 ws://(混合内容被浏览器阻止)
// const ws = new WebSocket('ws://your-domain.com/live'); // Blocked by browser!

// ✅ 开发环境(localhost + mkcert)
const ws = new WebSocket('wss://localhost:3000/live');

? 提示:Chrome 控制台 > Application > Frames 中可查看当前页面协议,确保 wss:// 连接来源与页面同源(协议+域名+端口)。

? 调试技巧

  1. 验证 HTTPS 是否真正启用:
    curl -I https://localhost:3000 应返回 HTTP/2 200 或 HTTP/1.1 200,且无证书警告。

  2. 测试 WSS 握手(命令行):

    # 使用 wscat(npm install -g wscat)
    wscat -c "wss://localhost:3000/live" --insecure  # --insecure 仅开发时跳过证书校验
  3. 检查 Fastify 日志级别:
    启用详细日志:logger: { level: 'trace' },观察是否有 upgrade 请求被拦截或 websocket: false 相关 warn。

✅ 总结:WSS 连接成功的三大前提

要素 要求 检查方式
服务端配置 https 选项必须在 fastify() 初始化时传入,且 @fastify/websocket 在其后注册 查看 fastify({ https: {...} }) 是否存在
TLS 证书 必须为浏览器信任的证书(mkcert / Let’s Encrypt),且 cert 包含完整链 openssl x509 -in cert.pem -text -noout \| grep "Issuer"
客户端连接 URL 协议(wss://)与页面协议一致,无跨域或混合内容限制 浏览器 Network 标签页查看 WebSocket 请求状态码

遵循以上方案,99% 的 Fastify + WSS 连接问题将迎刃而解。记住:WSS 不是“HTTPS 上的 WS”,而是基于 TLS 的独立协议通道,其握手、证书、端口均需端到端对齐。

热门AI工具

更多
WorkBuddy

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

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

豆包大模型

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

DeepSeek

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

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

相关专题

更多
chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

2966

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

6139

2023.11.06

Chrome开启无痕模式
Chrome开启无痕模式

本专题整合了Chrome无痕模式开启相关内容,阅读专题下面的文章了解更多详细教程。

4387

2026.03.24

curl_exec
curl_exec

curl_exec函数是PHP cURL函数列表中的一种,它的功能是执行一个cURL会话。给大家总结了一下php curl_exec函数的一些用法实例,这个函数应该在初始化一个cURL会话并且全部的选项都被设置后被调用。他的返回值成功时返回TRUE, 或者在失败时返回FALSE。

3903

2023.06.14

linux常见下载安装工具
linux常见下载安装工具

linux常见下载安装工具有APT、YUM、DNF、Snapcraft、Flatpak、AppImage、Wget、Curl等。想了解更多linux常见下载安装工具相关内容,可以阅读本专题下面的文章。

935

2023.10.30

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1069

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3460

2023.10.25

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6907

2023.07.18

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

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

80

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