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

Node.js与Next.js线上应用WebSocket无法通信,请求问题排查

问题分析与解决方案

核心问题

你的代码存在三个关键问题导致线上WebSocket无法通信:

  1. 后端未配置WSS(加密WebSocket)支持:当前用ws库直接创建的是普通ws://协议服务器,不支持加密的wss://连接。而线上前端是HTTPS环境,浏览器会强制阻止非加密的WebSocket连接;同时你直接给纯WebSocket服务器发HTTPS请求,就会返回「Upgrade Required」(需要升级协议)。
  2. 端口与协议不匹配:你访问https://backend.example.com用的是HTTPS默认443端口,但后端WebSocket服务器监听的是7500端口,且该端口只处理WebSocket协议,不处理普通HTTP/HTTPS请求,所以直接访问会报错。
  3. 跨域未配置:前后端域名不同(frontend.example.com和backend.example.com),浏览器的同源策略会阻止跨域WebSocket连接。

解决方案

方案一:将WebSocket挂载到已有的HTTPS服务器(推荐)

线上环境通常已有HTTPS服务(比如用Express搭建),把WebSocket服务器挂载到这个HTTPS服务器上,既能复用443端口的SSL证书,自动支持WSS,又能统一处理跨域。

修改后端代码:

const https = require('https');
const fs = require('fs');
const WebSocket = require('ws');

// 替换为你服务器的SSL证书路径
const sslOptions = {
  cert: fs.readFileSync('/etc/ssl/certs/your-cert.pem'),
  key: fs.readFileSync('/etc/ssl/private/your-key.pem')
};

// 创建HTTPS服务器(如果已有Express等服务器,直接用你的现有server即可)
const httpsServer = https.createServer(sslOptions);

// 挂载WebSocket服务器到HTTPS服务器
const wss = new WebSocket.Server({ server: httpsServer });

// 处理WebSocket连接
wss.on('connection', (ws, request) => {
  console.log('客户端已连接');
  
  // 处理客户端消息
  ws.on('message', (data) => {
    console.log('收到消息:', data);
    // 示例:广播消息给所有客户端
    wss.clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data);
      }
    });
  });
});

// 监听443端口(HTTPS默认端口)
httpsServer.listen(443, () => {
  console.log('HTTPS + WebSocket服务已启动,端口443');
});

修改前端连接地址:

ws.current = new WebSocket("wss://backend.example.com");

方案二:单独给WebSocket服务器配置SSL(不推荐)

如果不想依赖现有HTTPS服务器,可以直接给ws服务器配置SSL证书,监听7500端口:

后端代码修改:

const WebSocket = require('ws');
const fs = require('fs');

const wss = new WebSocket.Server({
  port: 7500,
  // 替换为你的SSL证书路径
  cert: fs.readFileSync('/etc/ssl/certs/your-cert.pem'),
  key: fs.readFileSync('/etc/ssl/private/your-key.pem')
}, () => {
  console.log('WSS服务已启动,端口7500');
});

// 处理连接和消息逻辑同方案一
wss.on('connection', (ws) => {
  // ...
});

前端连接地址保持:

ws.current = new WebSocket("wss://backend.example.com:7500");

注意:需要在服务器防火墙开放7500端口,且浏览器对非标准端口的WSS连接可能有额外限制,不如443端口稳定。


必须配置跨域

无论用哪种方案,都需要配置跨域允许,否则浏览器会阻止连接。以方案一为例,在HTTPS服务器的upgrade事件中添加跨域头:

httpsServer.on('upgrade', (request, socket, head) => {
  // 允许前端域名跨域
  socket.setHeader('Access-Control-Allow-Origin', 'https://frontend.example.com');
  socket.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  socket.setHeader('Access-Control-Allow-Headers', 'Content-Type');

  wss.handleUpgrade(request, socket, head, (ws) => {
    wss.emit('connection', ws, request);
  });
});

额外说明

直接访问https://backend.example.com显示「Upgrade Required」是正常现象,因为该地址对应的是WebSocket服务器,它只接受WebSocket协议的升级请求,不处理普通HTTP/HTTPS请求。测试WebSocket连接应该用前端代码,或者用命令行工具wscat:

wscat -c wss://backend.example.com

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:55:34