0

J'ai créé un backend GraphQL en utilisant Apollo Server, Sequelize (pour l'ORM), MySQL (DB) et Express (Web Server).Apollo Server Subscriptions ne fonctionne pas

J'ai également ajouté des abonnements, dont le problème est là. Je n'arrive même pas à atteindre le point de terminaison WS à l'aide d'un testeur de connexion Web. Est-ce que quelqu'un peut revoir mon code et me dire quel est le problème? J'ai regardé dans les docs, d'autres questions de stackoverflow et je ne peux pas trouver n'importe quelle solution.

Le code: https://github.com/seklyza/graphqlsubscriptions

Merci pour tout le monde

Répondre

0

Je pense que vous devez faire 2 serveurs une pour l'application qui utilise le serveur express et un pour le websocket. Ça pourrait ressembler à ça.

GraphQL serveur express:

... 
 

 
graphQLServer = express(); 
 

 
const GRAPHQL_PORT = 4000; 
 

 
graphQLServer.use('/graphql', bodyParser.json(), graphqlExpress((request) => { 
 
    return { 
 
    schema: executableSchema, 
 
    }; 
 
})); 
 

 
graphQLServer.use('/graphiql', graphiqlExpress({ 
 
    endpointURL: '/graphql', 
 
})); 
 

 
graphQLServer.listen(GRAPHQL_PORT,() => { 
 
    console.log(`GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql`); // eslint-disable-line no-console 
 
}); 
 

 
...

serveur websocket pour les abonnements:

... 
 

 
const WS_PORT = 8080; 
 

 
const websocketServer = createServer((request, response) => { 
 
    response.writeHead(404); 
 
    response.end(); 
 
}); 
 

 
websocketServer.listen(WS_PORT,() => console.log(// eslint-disable-line no-console 
 
    `Websocket Server is now running on http://localhost:${WS_PORT}` 
 
)); 
 

 
const subscriptionManager = new SubscriptionManager({ 
 
    schema: executableSchema, 
 
    pubsub: pubsub, 
 
    setupFunctions: { /* your subscription channels */ }, 
 
}); 
 

 
subscriptionServer = new SubscriptionServer({ 
 
    subscriptionManager: subscriptionManager 
 
}, { 
 
    server: websocketServer, 
 
    path: '/', 
 
}); 
 

 
...

Et vous avez besoin si rt du service d'abonnement à la publication, nous utilisons pubSub. Il est inclus dans le fichier du serveur et ressemble à ceci:

import { 
 
    PubSub 
 
} from 'graphql-subscriptions'; 
 

 
const pubsub = new PubSub(); 
 

 
export { 
 
    pubsub 
 
};

+0

J'ai également fait cela en utilisant 2 serveurs qui ne fonctionnaient pas. Je vais réessayer ... – shabenda

+0

A propos, comment spécifier dans GraphiQL l'URL du serveur d'abonnement? – shabenda

+0

Désolé je ne sais pas comment spécifier le serveur d'abonnement –

0

Vous pouvez créer une enveloppe de serveur socket web qui implémente la méthode start qui sera responsable de la création et l'exécution du WSServer, ainsi car il va créer un SubscriptionServer avec l'utilisation de SubscriptionManager

// in subscription.js 
import { PubSub, SubscriptionManager } from 'graphql-subscriptions'; 

const pubSub = new PubSub(); 

let subscriptionManagerOptions = { 
    schema: schema, // this is your graphql schema 
    setupFunctions: { 
     // here come your setup functions 
    }, 
    pubSub: pubSub 
}; 

const subscriptionManager = new SubscriptionManager(subscriptionManagerOptions); 

export { pubSub, subscriptionManager }; 

Après nous avons le subscriptionManager a créé, nous pouvons maintenant mettre en œuvre le WSServer

import { createServer } from 'http'; 
import { SubscriptionServer } from 'subscription-transport-ws'; 
import { subscriptionManager } from './subscription'; 

const webSocketServerWrapper = { 
    start: function(port){ 

     const webSocketServer = createServer((request, response) => { 
      response.writeHead(404); 
      response.end(); 
     });  

     webSocketServer.listen(port,() => { 
      console.log('WSServer listening on port ' + port); 
     }); 

     new SubscriptionServer({ 
      subscriptionManager, 
      onSubscribe: (message, options, request) => { 
       return Promise.resolve(Object.assign({}, options, {})); 
      } 
     }, webSocketServer); 

    } 
}; 

export default webSocketServerWrapper; 

Maintenant, vous pouvez importer le webSocketServerWrapper dans le fichier d'initialisation comme index.js et exécutez simplement webSocketServerWrapper.start(PORT);

Here, la deuxième réponse que j'ai écrit, vous pouvez trouver un code responsable de la création de l'exemple d'abonnement et de la façon dont il devrait être géré.

+0

Regardez les commentaires de l'autre réponse, et voir quel est le problème. – shabenda

+0

Comment essayez-vous de vous connecter à votre serveur ws? – piotrbienias

+0

Tout fonctionne maintenant. Merci – shabenda