Nest.js WebSocketGateway启用Socket.io确认回调遇阻求助
我懂你现在的困扰——想在Nest.js的WebSocketGateway里用上Socket.io的确认回调功能,就是那种客户端emit时带个回调函数,服务端处理完能触发它的机制对吧?确实Nest原生没直接支持这个,但咱们可以自己写个WebSocket适配器来搞定,我给你一步步拆解怎么做:
步骤1:创建自定义Socket.io适配器
首先新建一个socket-io.adapter.ts文件,继承Nest自带的IoAdapter,并重写createIOServer方法来处理socket的事件监听逻辑,把确认回调传递给Nest的消息处理器:
import { IoAdapter } from '@nestjs/platform-socket.io'; import { Server, Socket } from 'socket.io'; export class SocketIoAdapter extends IoAdapter { createIOServer(port: number, options?: any): Server { const server = super.createIOServer(port, options); server.on('connection', (socket: Socket) => { // 保存原生的socket.on方法 const originalOn = socket.on; // 重写socket.on,处理确认回调的传递 socket.on = (event: string, callback: (...args: any[]) => void) => { originalOn.call(socket, event, (...args: any[]) => { // 检查最后一个参数是不是函数(也就是确认回调) const ack = args.length > 0 && typeof args[args.length - 1] === 'function' ? args.pop() : undefined; // 把数据和ack回调一起传给Nest的消息处理器 callback(...args, ack); }); }; }); return server; } }
步骤2:在Nest应用中注册适配器
打开main.ts,把咱们自定义的适配器注册到应用里:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { SocketIoAdapter } from './socket-io.adapter'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 注册自定义WebSocket适配器 app.useWebSocketAdapter(new SocketIoAdapter(app)); await app.listen(3000); } bootstrap();
步骤3:在Gateway中使用确认回调
现在你的Gateway里的消息处理器就能接收ack参数了,像你期望的那样使用:
import { WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket } from '@nestjs/websockets'; import { Socket } from 'socket.io'; @WebSocketGateway() export class EventsGateway { @SubscribeMessage('event') onStart( @ConnectedSocket() client: Socket, @MessageBody() data: string, ack?: (response: string) => void, ) { // 这里处理你的业务逻辑 console.log('收到客户端数据:', data); // 如果存在确认回调,就触发它给客户端返回响应 if (ack) { ack('stuff completed'); } } }
客户端调用示例
客户端这边按照你原本的写法就可以正常工作了,比如浏览器里的Socket.io客户端:
const socket = io('http://localhost:3000'); socket.emit('event', 'some data', function(response) { console.log('服务端响应:', response); // 会打印 "服务端响应: stuff completed" });
关键原理说明
咱们自定义的适配器其实是重写了socket的on方法,当客户端触发事件时,我们先检查参数列表的最后一项是不是函数(也就是Socket.io的确认回调),如果是就把它从参数里抽出来,再和业务数据一起传给Nest的消息处理器,这样你的handler就能拿到ack并调用它了。
内容的提问来源于stack exchange,提问作者awnton
相关产品推荐
相关产品推荐

