代码之家  ›  专栏  ›  技术社区  ›  chris

如何在Apollo中关闭GraphQL订阅的套接字连接

  •  0
  • chris  · 技术社区  · 5 年前

    我的Apollo服务器上有GraphQL订阅,我想在用户注销后关闭。最初的问题是,我们应该在客户端还是后端关闭此(套接字)连接。

    在前端,我将Angular与Apollo客户端结合使用,并通过扩展GraphQL订阅来处理GraphQL订阅 Subscription 类从 apollo-angular 。我能够用典型的方式关闭订阅渠道 takeUntil rxjs实现:

    this.userSubscription
      .subscribe()
      .pipe(takeUntil(this.subscriptionDestroyed$))
      .subscribe(
        ({ data }) => {
          // logic goes here
        },
        (error) => {
          // error handling
       }
    );
      
    

    但是,这不会关闭服务器上的websocket,如果我是对的,这将导致订阅内存泄漏。

    Apollo服务器(和express)的订阅设置方式如下:

    const server = new ApolloServer({
      typeDefs,
      resolvers,
      subscriptions: {
        onConnect: (connectionParams, webSocket, context) => {
          console.log('on connect');
          const payload = getAuthPayload(connectionParams.accessToken);
          if (payload instanceof Error) {
            webSocket.close();
          }
          return { user: payload };
        },
        onDisconnect: (webSocket, context) => {
          console.log('on Disconnect');
        }
      },
      context: ({ req, res, connection }) => {
        if (connection) {
          // set up context for subscriptions...
        } else {
          // set up context for Queries, Mutations...
        }
    

    当客户端注册新的GraphQL订阅时,我总是会看到 console.log('on connect'); 在服务器日志上,但我从未看到 console.log('on Disconnect'); 除非我关闭前端应用程序。

    我还没有看到任何关于如何关闭Apollo订阅的websocket的示例。我主要想完成注销实现。

    我错过了什么吗?提前感谢!

    0 回复  |  直到 5 年前
        1
  •  4
  •   chris    4 年前

    我的解决方案基于此 post

    从本质上讲,我们使用套接字创建订阅的方式是 subscriptions-transport-ws

    export const webSocketClient: SubscriptionClient = new 
    SubscriptionClient(
      `${environment.WS_BASE_URL}/graphql`,
      {
        reconnect: true,
        lazy: true,
        inactivityTimeout: 3000,
        connectionParams: () => ({
          params: getParams()
        })
      }
    );
    

    正如问题中所述,我想在用户注销之前取消订阅所有频道并关闭订阅套接字连接。我们通过使用 webSocketClient SubscriptionClient在注销功能中调用:

    webSocketClient.unsubscribeAll();
    webSocketClient.close();