NestJS WebSocket无法同时兼容Postman与React Native客户端的解决方案咨询
解决NestJS WebSocket同时兼容React Native(Socket.IO)和Postman的问题
问题根源分析
你碰到的这个矛盾,本质是NestJS里两种WebSocket实现的冲突:
- 你写的
AppGateway用的是NestJS默认的Socket.IO方案,React Native里的socket.io-client刚好和它匹配,所以移除WsAdapter后RN能正常连接。 - 而
WsAdapter是NestJS用来适配**原生WebSocket(基于ws库)**的适配器,加上它之后,NestJS会把WebSocket服务切换成原生模式,这就和RN的Socket.IO客户端不兼容了,但Postman如果用原生WebSocket协议连接的话就能成功。
方案一:让Postman用Socket.IO方式连接(最省心)
其实Postman早就支持Socket.IO了,根本不用切换到原生WebSocket。按下面的步骤操作:
- 打开Postman,新建一个请求,选择
Socket.IO类型(不是WebSocket) - 输入服务地址:
http://localhost:3000 - 点击「Connect」建立连接
- 发送消息时,选择
Event类型,输入事件名msgToServer,然后在Payload里填你要发的内容(比如"test message") - 同时你可以在「Listeners」里添加
msgToClient,就能收到服务端广播的消息了
这样你只需要移除main.ts里的app.useWebSocketAdapter(new WsAdapter(app));,React Native和Postman就能同时正常工作,完全不用改后端代码。
方案二:同时支持Socket.IO和原生WebSocket(如果业务需要)
如果你确实需要同时兼容两种协议(比如还有其他原生WebSocket客户端),可以在NestJS里启动两个独立的WebSocket服务,分别对应Socket.IO和原生WebSocket:
1. 修改main.ts,启动两个服务
import { AppModule } from './app.module'; import { WsAdapter } from '@nestjs/platform-ws'; import { NestFactory } from '@nestjs/core'; async function bootstrap() { // 第一个服务:Socket.IO,给React Native用,端口3000 const socketIoApp = await NestFactory.create(AppModule); await socketIoApp.listen(3000); // 第二个服务:原生WebSocket,给Postman用,端口3001 const nativeWsApp = await NestFactory.create(AppModule); nativeWsApp.useWebSocketAdapter(new WsAdapter(nativeWsApp)); await nativeWsApp.listen(3001); console.log('Socket.IO服务运行在 http://localhost:3000'); console.log('原生WebSocket服务运行在 ws://localhost:3001'); } bootstrap();
2. 新建原生WebSocket网关
创建一个专门处理原生WebSocket的网关(和原来的AppGateway分开):
import { Logger } from '@nestjs/common'; import { OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, WebSocketGateway, WebSocketServer } from '@nestjs/websockets'; import { Server } from 'ws'; // 指定端口为3001,和main.ts里的配置对应 @WebSocketGateway({ port: 3001 }) export class NativeWsGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() server!: Server; private logger: Logger = new Logger('NativeWsGateway'); afterInit(server: Server) { this.logger.log('原生WebSocket服务初始化完成'); // 监听客户端消息并广播 server.on('connection', (socket) => { socket.on('message', (data) => { // 把收到的消息转发给所有连接的客户端 this.server.clients.forEach((client) => { if (client.readyState === client.OPEN) { client.send(`服务端收到:${data.toString()}`); } }); }); }); } handleDisconnect(client: any) { this.logger.log(`原生WebSocket客户端断开连接:${client._socket.remoteAddress}`); } handleConnection(client: any, ...args: any[]) { this.logger.log(`原生WebSocket客户端连接成功:${client._socket.remoteAddress}`); } }
3. 客户端连接方式
- React Native还是用原来的代码,连接
http://localhost:3000 - Postman选择
WebSocket类型,连接ws://localhost:3001,发送普通文本消息就能和服务端交互
总结
推荐优先用方案一,因为Postman支持Socket.IO,这样不需要额外维护两个服务,代码更简洁,也符合你原本的技术选型。
内容的提问来源于stack exchange,提问作者JN_newbie
相关产品推荐
相关产品推荐

