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

NestJS GraphQL订阅连接失败:无法连接WebSocket端点

问题解答

1. 自定义WebSocket适配器与graphql-ws是否存在冲突?

是的,存在冲突。当你通过app.useWebSocketAdapter(new WsAdapter(app))设置全局WebSocket适配器时,它会接管服务器的所有WebSocket连接处理逻辑,覆盖Apollo Server为GraphQL订阅(/graphql端点)预设的graphql-ws处理机制,导致订阅无法建立连接。

2. 如何让GraphQL订阅与自定义WebSocket网关共存?

核心思路是避免全局覆盖WebSocket处理逻辑,仅将自定义适配器应用到需要它的WebSocket网关,而非全局设置。具体步骤:

步骤1:移除全局WebSocket适配器配置

在main.ts中删除以下代码行:

app.useWebSocketAdapter(new WsAdapter(app));

步骤2:为单个WebSocket网关指定适配器

在你的自定义WebSocket网关类上,通过@WebSocketGateway装饰器的adapter选项指定WsAdapter:

import { WebSocketGateway } from '@nestjs/websockets';
import { WsAdapter } from '@nestjs/platform-ws';

@WebSocketGateway({
  adapter: WsAdapter,
  // 可添加其他网关配置,如path、port等
})
export class YourCustomGateway {
  // 网关逻辑...
}

这样,只有该自定义网关会使用WsAdapter,而Apollo Server的GraphQL订阅仍能正常处理/graphql端点的WebSocket连接。

3. 集成订阅是否需要额外配置?

除了上述调整,还需确认以下配置是否正确:

确认Apollo订阅配置

确保app.module.ts中的GraphQL订阅配置正确启用graphql-ws:

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
  subscriptions: {
    'graphql-ws': {
      // 可添加graphql-ws的额外配置,如onConnect、onDisconnect等
    },
  },
});

将true替换为配置对象可按需添加自定义逻辑,但基础启用只需设置为true即可。

验证依赖包完整性

确保已安装所有必需的依赖:

npm install graphql-ws @nestjs/graphql @nestjs/apollo apollo-server-express

测试订阅连接

调整配置后重启服务,使用GraphQL Playground或客户端工具测试订阅连接,端点应为ws://localhost:3000/graphql。

替代方案:使用混合适配器(高级场景)

如果必须全局设置适配器(例如多个网关共用同一适配器),可创建一个混合适配器,同时处理Apollo的GraphQL订阅和自定义WebSocket网关:

import { WsAdapter } from '@nestjs/platform-ws';
import { Server } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { GraphQLSchema } from 'graphql';

export class HybridWsAdapter extends WsAdapter {
  constructor(
    app: any,
    private readonly schema: GraphQLSchema,
  ) {
    super(app);
  }

  create(server: any): Server {
    const wsServer = super.create(server);
    
    // 为/graphql端点设置graphql-ws处理
    useServer(
      {
        schema: this.schema,
      },
      {
        server: wsServer,
        path: '/graphql',
      },
    );
    
    return wsServer;
  }
}

然后在main.ts中使用该混合适配器:

import { getSchema } from '@nestjs/graphql';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix('api');
  app.useGlobalPipes(new ValidationPipe());
  
  // 获取GraphQL schema并初始化混合适配器
  const schema = await app.get(getSchema());
  app.useWebSocketAdapter(new HybridWsAdapter(app, schema));
  
  await app.listen(3000);
}
bootstrap();

此方案适合需要全局适配器的复杂场景,但推荐优先使用单网关指定适配器的简单方案。

内容的提问来源于stack exchange,提问作者e-lab innovations

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:33:15