我正在使用 Apollo 客户端构建一个 graphql 服务器,它具有查询、订阅和变异功能。
我参考这个文档成功添加了查询:https://levelup.gitconnected.com/b-crud-operations-with-graphql-apollo-server-sequelize-auto-b-711da1803017
当我打开 http 链接时,它会将我带到 Apollo 沙箱。我这里可以查询。在此服务器的设置中有一个 websocket 链接。当我在我的 React 应用程序中使用此 websocket 链接时,通过使用 urql 和 GraphQLWsLink,它显示无法连接到 websocket。
我在我的服务器代码中配置了 websocket,如下所示:
const {createServer} = require('http');
const {ApolloServerPluginDrainHttpServer} = require('apollo-server-core');
const {ApolloServerPluginLandingPageLocalDefault} = require('apollo-server-core');
const {makeExecutableSchema} = require('@graphql-tools/schema');
const {WebSocketServer} = require('ws');
const {useServer} = require('graphql-ws/lib/use/ws');
const { ApolloServer,gql } = require('apollo-server');
var http = require("http");
const fs = require('fs');
const resolvers = require('./graphql/resolvers');
const typeDefs = gql(fs.readFileSync('./graphql/typeDefs.graphql',{encoding:'utf-8'}));
console.log("Resolvers", resolvers)
const app = new ApolloServer({typeDefs,resolvers });
const schema = makeExecutableSchema({ typeDefs, resolvers });
// ...
const httpServer = createServer(app);
// Creating the WebSocket server
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql',
});
const serverCleanup = useServer({ schema }, wsServer);
const server = new ApolloServer({
schema,
csrfPrevention: true,
cache: "bounded",
plugins: [
// Proper shutdown for the HTTP server.
ApolloServerPluginDrainHttpServer({ httpServer }),
// Proper shutdown for the WebSocket server.
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
ApolloServerPluginLandingPageLocalDefault({ embed: true }),
],
});
server.listen(5000).then(({ url }) => {
console.log("Server ready at " + url );
});
客户端(react)代码如下:
const serverURL = "http://127.0.0.1:5000/graphql";
const wsClient = new GraphQLWsLink(createClient({
url: 'ws://127.0.0.1:5000/graphql',
}));
const client = createClient({
url: senseopsHTTPServerURL,
exchanges: [
...defaultExchanges,
subscriptionExchange({
forwardSubscription: (operation) => ({
subscribe: (sink) => ({
unsubscribe: wsClient.subscribe(operation, sink),
}),
}),
}),
],
});
我在上下文提供程序中使用此客户端来获取数据。它显示“无法连接到 websocket”。我该如何解决这个问题?
这是我在 ws 上初始化 Graphql 的代码。
// Importation des modules nécessaires
const WebSocket = require("ws");
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const { createServer } = require('http');
const { makeExecutableSchema } = require('@graphql-tools/schema');
// const { useServer } = require('@graphql-tools/lib/use/ws');
const { WebSocketServer } = require('ws');
// Schéma GraphQL
const typeDefs = gql`
type Chat {
id: ID!
clientName: String
messagePreview: String
timestamp: String
}
type Query{
pendingChats:[Chat]
}
`;
// Résolveurs GraphQL
const resolvers = {
Query: {
hello: () => 'Bonjour, GraphQL et WebSocket!',
},
Query: {
pendingChats: async () => {
// Simulation de la base de données
return [
{ id: '1', clientName: 'Alice', messagePreview: 'Bonjour...', timestamp: '2024-12-25T10:00:00Z' },
{ id: '2', clientName: 'Bob', messagePreview: 'Avez-vous reçu...', timestamp: '2024-12-25T09:45:00Z' }
];
}
}
};
// Créer le schéma GraphQL
const schema = makeExecutableSchema({ typeDefs, resolvers });
// Initialisation d'Express
const app = express();
// Middleware Express (routes classiques)
app.get('/', (req, res) => {
res.send('Bienvenue sur le serveur combiné Apollo + WebSocket!');
});
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
// Créer le serveur HTTP
const httpServer = createServer(app);
// Configurer Apollo Server
const apolloServer = new ApolloServer({
schema,
plugins: [
{
async serverWillStart() {
return {
async drainServer() {
await wsServer.dispose();
},
};
},
},
],
});
// Configurer Apollo Server avec Express
(async () => {
await apolloServer.start();
apolloServer.applyMiddleware({ app });
// Créer un serveur WebSocket
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql',
});
// Liste des connexions actives
const clients = new Set();
// Gestion des connexions WebSocket
wsServer.on("connection", (ws) => {
console.log("Un client est connecté !");
clients.add(ws);
// Événement : réception d'un message
ws.on("message", (message) => {
console.log(`Message reçu : \${message}`);
// Diffuser le message à tous les clients
for (const client of clients) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(message);
}
}
});
// Événement : déconnexion
ws.on("close", () => {
console.log("Un client s'est déconnecté.");
clients.delete(ws);
});
// Envoyer un message de bienvenue au client
ws.send("Bienvenue sur le tchat !");
});
// Intégrer GraphQL WebSocket Server
//useServer({ schema }, wsServer);
// Démarrer le serveur HTTP
const PORT = 3000;
httpServer.listen(PORT, () => {
console.log(`Serveur HTTP démarré sur http://localhost:\${PORT}`);
console.log(`Apollo Server disponible sur http://localhost:\${PORT}/graphql`);
console.log(`WebSocket Server démarré sur ws://localhost:\${PORT}/graphql`);
});
})();