Apollo 服务器订阅不起作用

Posted

技术标签:

【中文标题】Apollo 服务器订阅不起作用【英文标题】:Apollo Server Subscriptions not working 【发布时间】:2017-08-12 17:41:32 【问题描述】:

我使用 Apollo Server、Sequelize(用于 ORM)、mysql(DB)和 Express(Web 服务器)制作了一个 GraphQL 后端。

我还添加了订阅,问题就在那里。 我什至无法使用 websocket 测试器到达 WS 端点。

有人可以查看我的代码并告诉我问题所在吗?我查看了文档和其他 *** 问题,但找不到任何解决方案。

代码:https://github.com/seklyza/graphqlsubscriptions

谢谢大家

【问题讨论】:

【参考方案1】:

我认为您必须为使用 express 服务器的应用程序制作 2 个服务器,而为 websocket 制作一个。它可能看起来像这样。

GraphQL 快递服务器:

...

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
);

...

用于订阅的 websocket 服务器:

...

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: '/',
);

...

您需要某种出版物订阅服务,我们使用pubSub。它包含在服务器文件中,如下所示:

import 
  PubSub
 from 'graphql-subscriptions';

const pubsub = new PubSub();

export 
  pubsub
;

【讨论】:

我也使用了 2 台无法正常工作的服务器来做到这一点。我会再试一次... 顺便问一下,如何在 GraphiQL 中指定订阅服务器 URL? 抱歉我不知道如何指定订阅服务器 还是不行。我什至无法使用 websocket 客户端连接到 WS 服务器。查看 GitHub 上的新代码。 能否尝试更新subscriptions-transport-ws 包并使用subscriptionServer = new SubscriptionServer( subscriptionManager: subscriptionManager , server: websocketServer, path: '/', );【参考方案2】:

您可以创建一些实现start 方法的Web 套接字服务器包装器,该方法将负责创建和运行WSServer,以及使用SubscriptionManager 创建一个SubscriptionServer

// 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 ;

创建subscriptionManager 后,我们现在可以实现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;

现在您可以在初始化文件中导入webSocketServerWrapper,例如index.js,然后运行webSocketServerWrapper.start(PORT);

Here,我写的第二个答案,你可以找到负责创建示例订阅的代码以及如何处理它。

【讨论】:

看看其他答案的cmets,看看是什么问题。 你如何尝试连接到你的ws服务器? 那么问题出在哪里?

以上是关于Apollo 服务器订阅不起作用的主要内容,如果未能解决你的问题,请参考以下文章

订阅在 React Native 中不起作用?

Apollo 网关在 docker-compose 中不起作用

导入另一个文件时,Apollo 反应变量不起作用!为啥?

Apollo graphql 将标头设置为 authmiddleware 不起作用

Apollo 的检查并运行 apollo-codegen.sh 不起作用?

Apollo 客户端持久缓存不起作用