Graphql-ws: separate websocket connection is opened for each subscription

1.6k Views Asked by At

I'm a newbie in websockets. I use urql and graphql-ws (migrated from subscriptions-transport-ws) to get graphql subscriptions. The code is following:

export const useUrqlClient = () => {
  const headers = useHeaders();
  const client = useMemo(() => createUrqlClient(headers), [headers]);
  return client;
};

const createUrqlClient = (headers: any = defaultHeaders) => {
  return createClient({
    url: GRAPHQL_ENDPOINT,
    fetchOptions: {
      headers
    },
    exchanges: [
      ...defaultExchanges,
      subscriptionExchange({
        forwardSubscription: (operation) => {
          return {
            subscribe: (sink) => ({
              unsubscribe: wsClient(headers).subscribe(operation, sink)
            })
          }
        }
      })
    ]
  });
};

const wsClient = (headers: any) => createWSClient({
  url: WS_GRAPHQL_ENDPOINT,
  connectionParams: () => ({
    headers
  })
});

const useHeaders = () => {
  const [authHeader, setAuthHeader] = useState<object>({});
  const { selectedToken } = useAuth();

  useEffect(() => {
    if (selectedToken) {
      setAuthHeader(selectedToken ? { authorization: `Bearer ${selectedToken}` } : {});
    }
  }, [selectedToken]);

  return {
    ...defaultHeaders,
    ...authHeader
  };
};

Everything works fine BUT is it okay that separate websocket connection is opened for each subscription? enter image description here

They are closed on leaving the page and another are created but is it expected?

Note: the same behaviour was on approach using subscriptions-transport-ws.

1

There are 1 best solutions below

0
On

You're running the client in lazy mode which establishes WebSocket connections on-demand, this is the default.

Consider one of the 2 options:

  1. Use the client in lazy = false mode which will establish a connection with the server on create and keep it alive
  2. Use the client's lazyCloseTimeout option which will delay closing the connection in case of new subscriptions.