Hi all!
I have a graphql api with apollo server and graphql-ws and I have a subscription, the first time that I run the server, the client subscription is correctly executed, when I reload the page and the client try to subscribe again, looks like the connection is still alive and I just see that the server is executing the hook.
onComplete: async (connectionParams) => {
console.log('onComplete connectionParams', connectionParams);
},
and after that is executing the hook
onDisconnect: async (connectionParams) => {
console.log('onDisconnect connectionParams', connectionParams);
},
so to have the connection again, I need to kill my server and re-run it again, and the client can subscribe again.
This is my implementation
import { ApolloServer } from '@apollo/server';
import gql from 'graphql-tag';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { makeExecutableSchema } from '@graphql-tools/schema';
import * as express from 'express';
import { createServer } from 'http';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import * as cors from 'cors';
import { expressMiddleware } from '@apollo/server/express4';
import typeDefsGraphql from './src/graphql/schema.graphql';
import * as dotenv from 'dotenv';
import resolvers from './src/graphql/resolvers';
import PubSubManager from './src/services/pubsub/PubSubManager';
import CustomRedisPubSub from './src/services/pubsub/clients/CustomRedisPubSub';
dotenv.config();
const PORT = 4001;
const PATH = '/subscriptions';
async function start(): Promise<void> {
const app = express();
const httpServer = createServer(app);
const typeDefs = gql`
${typeDefsGraphql}
`;
const pubsub = new PubSubManager(new CustomRedisPubSub());
const schema = makeExecutableSchema({
typeDefs,
resolvers: await resolvers({ pubsub }),
});
const wsServer = new WebSocketServer({
server: httpServer,
path: PATH,
});
const serverCleanup = useServer(
{
schema,
context: async (params) => {
return {
headers: params?.connectionParams,
};
},
onConnect: async (connectionParams) => {
console.log('onConnect connectionParams', connectionParams);
},
onDisconnect: async (connectionParams) => {
console.log('onDisconnect connectionParams', connectionParams);
},
onError: async (connectionParams) => {
console.log('onError connectionParams', connectionParams);
},
onComplete: async (connectionParams) => {
console.log('onComplete connectionParams', connectionParams);
},
},
wsServer,
6_000,
);
const server = new ApolloServer({
schema,
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
],
});
await server.start();
app.use(
PATH,
cors<cors.CorsRequest>(),
express.json(),
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
expressMiddleware(server),
);
// eslint-disable-next-line @typescript-eslint/no-misused-promises
httpServer.listen(PORT, async () => {
console.log(`Server is now running on http://localhost:${PORT}${PATH}`);
console.log(`Server is now running on ws://localhost:${PORT}${PATH}`);
});
}
void start();