Together with a colleague, I set up an Apollo Supergraph that includes support for GQL subscriptions.
graph TD
    A[Gateway\n&\n Websocket Proxy] -- HTTP --> B((GraphQL\nServer))
    A -- WebSocket --> C((Subscriptions\nServer))
Details of the supergraph
We put the old GraphQL server and the subscriptions server behind the gateway server, and then we set up a WebSocket proxy server to proxy the connections to the subscriptions server.
This is the base of the gateway server:
import { ApolloServer } from "@apollo/server";
import { ApolloGateway } from "@apollo/gateway";
import { createServer } from "http";
import express from "express";
import { createServer as createProxy } from "http-proxy";
const proxy = createProxy({
  target: "ws://localhost:4002/subscriptions",
  ws: true,
  changeOrigin: true,
});
const app = express();
const httpServer = createServer(app);
const supergraphSdl = new IntrospectAndCompose({
  subgraphs: [
    {
      name: "gql",
      url: "http://localhost:4001/graphql",
    },
    {
      name: "sub",
      url: "http://localhost:4002/graphql",
    },
  ],
});
const gateway = new ApolloGateway({
  supergraphSdl,
});
const server = new ApolloServer({
  gateway,
});
httpServer.on("upgrade", (req, socket, head) => {
  proxy.ws(req, socket, head);
});
httpServer.listen(4000, () => {
  console.log(`🚀 Server ready at http://localhost:4000/graphql`);
});