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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:35:28