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

Nest.js集成WebSocket配置后浏览器端连接失败问题咨询

问题根因
  • 协议适配不匹配:@WebSocketGateway() 默认基于socket.io实现,和浏览器原生WebSocket API协议不兼容,原生客户端无法直接握手连接。
  • 连接参数错误:配置了namespace: 'events'但连接地址未携带命名空间;本地开发未配置SSL证书时使用wss://协议会触发证书校验失败;未指定服务端口时默认请求443端口,和本地Nest服务实际监听端口(通常为3000)不匹配。
  • 配置缺失:未开启跨域配置时浏览器会拦截跨域WS请求;未安装对应WebSocket适配依赖时网关不会正常启动。
可运行实现示例

方案1:使用默认socket.io适配(官方推荐,功能更完善)

  1. 安装依赖
npm i @nestjs/websockets @nestjs/platform-socket.io socket.io
  1. 网关代码(修正配置)
import { WebSocketGateway, SubscribeMessage, WebSocketServer, WsResponse } from '@nestjs/websockets';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Server } from 'socket.io';

@WebSocketGateway({
  path: '/api',
  namespace: 'events',
  cors: { origin: "*" } // 本地开发放开跨域限制
})
export class EventGateway {
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('events')
  findAll(): Observable<WsResponse<number>> {
    return from([1, 2, 3]).pipe(
      map((item) => ({ event: 'events', data: item })),
    );
  }

  @SubscribeMessage('identity')
  async identity(client: any, data: number): Promise<number> {
    return data;
  }
}

确保EventGateway已加入AppModule的providers数组。
3. 客户端连接代码(使用socket.io-client)
先安装客户端依赖:npm i socket.io-client

import { io } from "socket.io-client";

// 替换3000为你Nest服务实际监听端口
const socket = io('ws://localhost:3000/events', {
  path: '/api'
});

socket.on('connect', () => {
  console.log('连接成功,socketID:', socket.id);
  // 测试identity接口
  socket.emit('identity', 123, res => console.log('identity返回值:', res));
  // 监听服务端推送的events事件
  socket.on('events', data => console.log('收到events数据:', data));
  // 触发events事件
  socket.emit('events');
});

socket.on('connect_error', err => console.log('连接异常:', err));

方案2:使用原生WS适配(支持浏览器原生WebSocket对象连接)

如果必须使用原生WebSocket API连接,替换默认适配器即可:

  1. 安装依赖
npm i @nestjs/platform-ws ws
  1. 在main.ts中注册WS适配器
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from '@nestjs/platform-ws';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useWebSocketAdapter(new WsAdapter(app)); // 替换为原生ws适配器
  await app.listen(3000); // 端口自行替换
}
bootstrap();
  1. 修改网关配置(原生ws不支持namespace,删除该字段)
@WebSocketGateway({
  path: '/api',
})
export class EventGateway {
  // 原有业务逻辑无需修改
}
  1. 浏览器端原生连接代码
// 替换3000为实际服务端口,本地无证书用ws协议不要用wss
const ws = new WebSocket('ws://localhost:3000/api');
ws.onopen = () => {
  console.log('连接成功');
  // 原生ws需要手动序列化消息,Nest WS适配器默认识别{event: string, data: any}格式
  ws.send(JSON.stringify({event: 'identity', data: 456}));
  ws.send(JSON.stringify({event: 'events', data: null}));
};
ws.onmessage = msg => {
  const payload = JSON.parse(msg.data);
  console.log('收到消息:', payload);
};
ws.onerror = err => console.log('连接异常:', err);
排查方向
  • 启动Nest服务时查看控制台日志,确认网关成功启动,无依赖缺失、注册错误提示。
  • 核对连接地址:端口和服务监听端口一致、本地开发用ws://而非wss://、socket.io模式下路径和命名空间配置和服务端匹配。
  • 检查网关跨域配置,本地开发可临时放开origin限制,部署时按实际域名配置白名单。
  • 打开浏览器F12控制台,查看Network面板中WS请求的错误码:404对应路径配置错误、证书错误对应协议使用错误、CORS报错对应跨域配置缺失。
  • 使用socket.io模式时,确保客户端和服务端socket.io大版本一致,版本不兼容会导致握手失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:48:16