How do you shut down a stale Apollo-Client websocket connection?
Asked Answered
D

1

7

I have a page that is loading connected apollo-client pages as widgets inside of a main page. My GraphQL server is self-hosted. They are served up through iFrame (self-hosted), connecting back to my own server. Communications are done through a 3rd party's iFrame communications SDK.

For some reason the widgets are not cleared out from the window when they are stale (I have no control over this). However I do have access to know when they are "stale". When they turn stale I want to disconnect / shutdown the websocket connection. The trouble is the still-connected clients are eating up my back-end's CPU. I am watching the websocket connection through chrome dev-tools. I notice every 5 seconds it sends a keep-alive request to the websocket sever. Every so often I see a stop request, and I want to figure out how to replicate that.

Im my react apollo-connected component I tried calling these two commands, but after they are called with no errors, the keep-alive flags are still being sent to the websocket server.

this.props.client.stop()
this.props.client.clearStore();

How do I tell the apollo-client to shut itself down?

Danikadanila answered 17/10, 2019 at 17:37 Comment(2)
Did you find a fix for this ?Gardia
Did you find a fix for this?Exurb
E
0

For Apollo V3, the WebSocketLink has an internal SubscriptionClient instance, but the problem is that WebSocketLink doesn't expose methods that give you access to the SubscriptionClient instance, so there's no accessing SubscriptionClient.close(). Fortunately, WebSocketLink accepts a client as an argument:

const subscriptionClient = new SubscriptionClient(`wss://example.com/subscriptions`, {
  // example options:
  reconnect: true,
  lazy: true,
  connectionParams: () => ({ accessToken: 'secret' }),
});

const wsLink = new WebSocketLink(subscriptionClient);

Now you just need to move subscriptionClient into a context in order to gain access to the client in various places:

export const SubscriptionClientContext = createContext<
  SubscriptionClient | undefined
>(undefined);
export const useSubscriptionClient = (): SubscriptionClient => {
  const subscriptionClient = useContext(SubscriptionClientContext);
  if (subscriptionClient === undefined) {
    throw Error(
      'SubscriptionClient not initiated, can only be called inside SubscriptionClientContext.Provider',
    );
  }
  return subscriptionClient;
};

<SubscriptionClientContext.Provider value={subscriptionClient}>
  <App />
</SubscriptionClientContext.Provider>

This will let you access methods on the client for logout behavior in various parts of the app:

const subscriptionClient = useSubscriptionClient();

subscriptionClient.close();

There are also two arguments for .close, that have various behaviors. E.g. close and reconnect, close and do not reconnect.

Exurb answered 8/3, 2022 at 18:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.