如何将 socket.io 与 graphql 订阅一起使用?

Posted

技术标签:

【中文标题】如何将 socket.io 与 graphql 订阅一起使用?【英文标题】:How to use socket.io with graphql subscription? 【发布时间】:2020-10-21 01:24:29 【问题描述】:

我想用nestjs和graphql技术做一个实时聊天应用。大多数教程都使用 PubSub,但我不知道如何向特定客户端发送消息(?)。 我认为使用 socket.io 通过使用套接字 id 向特定客户端发送消息非常容易。

这个使用 PubSub 的例子:

    是否可以使用 PubSub 向特定客户端发送消息?通过接收一些关于发件人的数据,例如 id。 如何将 PubSub 替换为 Socket.io?我对 socket.io 非常满意

App.module.ts

import  Module, MiddlewareConsumer, RequestMethod, Get  from '@nestjs/common';
import  TypeOrmModule  from '@nestjs/typeorm';
import  typeOrmConfig  from './config/typeorm.config';
import  AuthModule  from './auth/auth.module';
import  LoggerMiddleware  from './common/middlewares/logger.middleware';
import  Connection  from 'typeorm';
import  GraphQLModule  from '@nestjs/graphql';
import  join  from 'path';
import  ChatModule  from './chat/chat.module';
import  ChatService  from './chat/chat.service';

@Module(
  imports: [
    TypeOrmModule.forRoot(typeOrmConfig), // connect to database
    GraphQLModule.forRoot(
      debug: true,
      playground: true,
      typePaths: ['**/*.graphql'],
      definitions: 
        path: join(process.cwd(), 'src/graphql.ts'),
      ,
    ),
    AuthModule,
    ChatModule,
  ],
  controllers: [],
  providers: [
  ],
)
export class AppModule 

聊天模块.ts

import  Module  from '@nestjs/common';
import  ChatService  from './chat.service';
import  ChatResolver  from './chat.resolver';
import  TypeOrmModule  from '@nestjs/typeorm';
import  AuthModule  from '../auth/auth.module';
import  PubSub  from 'graphql-subscriptions';

@Module(
  imports: [
    // Add all repository here; productRepository, ...
    TypeOrmModule.forFeature( [
      // repositories ...
    ]),
    AuthModule
  ],
  providers: [
     //=> How to replace with socket.io ?
     
       provide: 'PUB_SUB',
       useValue: new PubSub(),
    ,
    ChatService, 
    ChatResolver,
  ]
)
export class ChatModule 

Chat.resolver.ts

import  Resolver, Query, Mutation, Args, Subscription  from '@nestjs/graphql';
import  PubSubEngine   from 'graphql-subscriptions';
import  Inject  from '@nestjs/common';

const PONG_EVENT_NAME = 'pong';

@Resolver('Chat')
export class ChatResolver 
    constructor(
        private chatService: ChatService,

        @Inject('PUB_SUB') 
        private pubSub: PubSubEngine,
    ) 

    // Ping Pong
    @Mutation('ping')
    async ping() 
        const pingId = Date.now();
        //=> How to send deta to specific client by using user-id?
        this.pubSub.publish(PONG_EVENT_NAME,  ['pong']:  pingId  );
        return  id: pingId ;
    

    @Subscription(PONG_EVENT_NAME)
    pong() 
        //=> how to get data about sender like id?
        return this.pubSub.asyncIterator(PONG_EVENT_NAME);
    


Chat.graphql

type Mutation 
    ping: Ping


type Subscription 
  tagCreated: Tag
  clientCreated: Client
  pong: Pong


type Ping 
  id: ID


type Pong 
  pingId: ID

如何用 Socket.io 替换 PubSub?

【问题讨论】:

【参考方案1】:

我没有找到任何从 graphql 订阅中获取客户端套接字的解决方案或示例。 在大多数示例中,他们使用网关而不是 graphql pubsub。所以我使用 GateWay 来实现实时活动和 graphql 来处理其他请求。

【讨论】:

以上是关于如何将 socket.io 与 graphql 订阅一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Asterisk ARI 与 socket.io 和 Node.js 一起使用

将socket.io与sails js一起使用

如何使用 Socket.io 和 Express 进行集群

如何将 Apache 配置为代理 socket.io 服务器

如何通过 Websocket 协议处理 GraphQL 中的文件上传?

与 socket.io 私聊