NestJS WebSocket Gateway中this.server.of不是函数的问题求助
问题原因分析
当你在@WebSocketGateway中指定了namespace: '/chat'时,@WebSocketServer()装饰器注入的server其实是Socket.IO的Namespace(命名空间)实例,而非顶层的全局Socket.IO Server实例。of()是全局Server独有的方法,用于获取或创建新的命名空间,Namespace实例并不具备这个方法,因此调用this.server.of('/users')会触发TypeError: this.server.of is not a function错误。
解决方案
下面提供两种可行的解决方式,都能实现跨命名空间发送消息的需求:
方案1:注入全局Socket.IO Server实例
通过Nest提供的SOCKET_IO_SERVER令牌注入全局Server,直接调用其of()方法切换命名空间:
import { Inject } from '@nestjs/common'; import { WebSocketGateway, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage } from '@nestjs/websockets'; import { Namespace, Server, Socket } from 'socket.io'; import { SOCKET_IO_SERVER } from '@nestjs/platform-socket.io'; @WebSocketGateway(3002, { namespace: '/chat', }) export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() private chatServer: Namespace; // 明确类型为命名空间实例 constructor( @Inject(SOCKET_IO_SERVER) private readonly globalServer: Server, // 注入全局Server private readonly connectionsService: ConnectionsService, private readonly usersService: UsersService, ) {} // ... 其余连接/断开逻辑保持不变 @SubscribeMessage('chat:message') async handleMessage(client: Socket, payload: any) { try { const allConnections = await this.connectionsService.findAll('1234'); // 使用全局Server切换到/users命名空间发送消息 this.globalServer .of('/users') .to('5678') .emit('chat:responseAll', allConnections); } catch (error) { console.error('-----', error); } } }
方案2:通过客户端实例获取全局Server
每个Socket客户端实例的server属性指向全局Socket.IO Server,可直接利用这一点切换命名空间:
@SubscribeMessage('chat:message') async handleMessage(client: Socket, payload: any) { try { const allConnections = await this.connectionsService.findAll('1234'); // 通过client.server获取全局Server,再切换命名空间 client.server .of('/users') .to('5678') .emit('chat:responseAll', allConnections); } catch (error) { console.error('-----', error); } }
额外提示
建议修正@WebSocketServer()注入变量的类型,将原来的Server改为Namespace,这样TypeScript会提供更准确的类型提示,避免后续类型混淆问题。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

