Web socket connection fails for Node.js graphql api

So I need the Subscription mechanism for a GraphQL API that I've done for some server side notifications. For the config of API apollo-server-express was used. Here is the config file:

dotenv.config();
const PORT = process.env.PORT;
const app = express();
const httpServer = createServer(app);


const wsServer = new WebSocketServer({
  server: httpServer,
  path: '/graphql'
});

const serverCleanup = useServer({ schema }, wsServer);

const server = new ApolloServer({
  schema,
  plugins: [
    // ApolloServerPluginDrainHttpServer({ httpServer }),
    {
      async serverWillStart() {
        return {
          async drainServer() {
            await serverCleanup.dispose();
          }
        };
      }
    }
  ],
  // context: ({ req, res }) => ({ req, res})
});

server.start().then(async () => {
  connectToDatabase().then(() => {
    console.warn('Connected successfully to db');
    app.use((req, res, next) => {
      console.log('Request arrived');
      next();
    });
    configRepository().then((res) => {
      console.warn('Repo configured');
      configService(res).then(() => {
        console.warn('Service configured');
        server.applyMiddleware({ app, path: '/graphql' });
        httpServer.listen(PORT);
        console.warn('Server started');
      });
    });
  }).catch(e => console.log(e));
});

The graphql subscription:

extend type Subscription {
    commentsNotification(token:String!): CommentNotification
}

The subscription resolver looks like this:

const pubsub = new PubSub();

export const CommentsResolver = (services: ServiceConfig) => ({
///... query and mutation resolve functions,
Subscription: {
    commentsNotification: {
      subscribe: (token: String) => pubsub.asyncIterator('COMMENTS_NOTIFICATION')
    }
  }
})

When using the apollo server sandbox, and calling the subscription this messages are received:

  1. WebSocket connection to 'ws://localhost:8080/graphql' failed
  2. WebSocket connection to 'ws:/graphql' failed: WebSocket is closed before the connection is established.

Is something that I did wrong in the configuration of the server? Or am I missing something? Thank you

Upvotes: 1

Views: 1194

Answers (1)

izidormaklary
izidormaklary

Reputation: 71

I think you are having issues because you are not actually "using" your websocket server. In case you are using graphql-ws you have to use the useServer method, where you will have to pass in your schema and web-socket server instance.

let graphqlWSServer;
...

server.start().then(async () => {
    connectToDatabase().then(() => {
        console.warn('Connected successfully to db');
        app.use((req, res, next) => {
            console.log('Request arrived');
            next();
        });
        configRepository().then((res) => {
            console.warn('Repo configured');
            configService(res).then(() => {
                 console.warn('Service configured');
                 server.applyMiddleware({ app, path: '/graphql' });
                 httpServer.listen(PORT);
                 // missing line below
                 graphqlWSServer = useServer({ schema: getSubscriptionSchema() }, wsServer);
                 console.warn('Server started');
            });
        });
    }).catch(e => console.log(e));
});

Upvotes: 0

Related Questions