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

如何将socket.io实例传递到typegraphql resolver中?

解决方案:在TypeGraphQL Resolver中复用Socket.IO单实例发送房间事件

你遇到的导出后拿到新实例的问题,通常由三个原因导致:

  • 拼写错误:你代码里写的modules.export多了一个s,正确导出语法是module.exports = io,拼写错误会导致导出失效,拿到undefined,如果你的逻辑里判断实例不存在就新建,就会生成新实例
  • 循环依赖:初始化Socket.IO的文件依赖Resolver相关代码,Resolver又反过来导入IO实例,Node.js模块缓存未完成IO实例导出就被Resolver引入,拿到空值后重复初始化
  • 导出的是IO创建函数而非初始化完成的实例,每次导入调用都会生成新实例

下面是两种可直接落地的解决方案:

方案1:单例模式封装IO实例(无额外依赖)

  • 第一步:新建单独的IO实例管理文件,避免循环依赖
// src/utils/socket-io.js
let ioInstance = null;

// 全局仅初始化一次实例
exports.setIOInstance = (io) => {
  ioInstance = io;
};

// 所有业务场景共用同一个实例
exports.getIOInstance = () => {
  if (!ioInstance) throw new Error("Socket.IO 实例未初始化");
  return ioInstance;
};
  • 第二步:在入口文件初始化IO后,先存实例再加载Resolver、启动服务
// index.js
const { Server } = require("socket.io");
const { setIOInstance } = require("./src/utils/socket-io");
const { buildSchema } = require("type-graphql");
// 其他基础依赖引入

const httpServer = // 你的HTTP服务实例,可基于express、koa等创建
const io = new Server(httpServer, {
  // 你的Socket.IO配置,比如cors规则等
});

// 先存入实例,再执行后续Resolver加载、服务启动逻辑
setIOInstance(io);

// 再构建TypeGraphQL Schema
const schema = await buildSchema({
  resolvers: [/* 你的Resolver列表 */],
  // 其他Schema配置
});
// 后续启动HTTP服务、GraphQL服务的逻辑
  • 第三步:在Resolver中直接获取实例发送事件
// 你的业务Resolver文件
const { getIOInstance } = require("../utils/socket-io");
const { Resolver, Mutation, Arg } = require("type-graphql");

@Resolver()
class RoomResolver {
  @Mutation(() => Boolean)
  async sendRoomEvent(@Arg("roomId") roomId, @Arg("message") message) {
    const io = getIOInstance();
    // 向指定房间发送事件
    io.to(roomId).emit("room_notification", message);
    return true;
  }
}

方案2:依赖注入方案(适配TypeGraphQL生态)

如果你已经在TypeGraphQL中使用typedi做依赖注入,可以直接把IO实例注入到Resolver中,代码更简洁:

  • 第一步:入口文件初始化IO后存入容器
const { Container } = require("typedi");
// IO初始化完成后
Container.set("SOCKET_IO_INSTANCE", io);
  • 第二步:在Resolver中注入实例使用
const { Resolver, Mutation, Arg, Inject } = require("type-graphql");
const { Server } = require("socket.io");

@Resolver()
class RoomResolver {
  @Inject("SOCKET_IO_INSTANCE")
  /** @type {Server} */
  io;

  @Mutation(() => Boolean)
  async sendRoomEvent(@Arg("roomId") roomId, @Arg("message") message) {
    this.io.to(roomId).emit("room_notification", message);
    return true;
  }
}

内容的提问来源于stack exchange,提问作者Timofey Melentev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 21:24:00