【问题标题】:Subscription not connecting using ApolloServer订阅未使用 ApolloServer 连接
【发布时间】:2019-04-24 05:06:06
【问题描述】:

我正在尝试使用 ApolloServer (v 2.2.2) 启动和运行订阅。我有一个突然停止工作的设置。当我尝试连接到graphiql/Playground中的订阅时,出现错误:

{
  "error": "Could not connect to websocket endpoint ws://localhost:4000/graphql. Please check if the endpoint url is correct."
}

由于我的应用程序中有休息端点,我需要使用 express,但我无法从下面运行的最小示例中获得:

import http from 'http';
import { ApolloServer, PubSub } from 'apollo-server-express';
import express from 'express';

const pubsub = new PubSub();

// The DB
const messages = [];

const typeDefs = `
type Query {
  messages: [String!]!
}
type Mutation {
  addMessage(message: String!): [String!]!
}
type Subscription {
  newMessage: String!
}

schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}
`;

const resolvers = {
  Query: {
    messages() {
      return messages;
    }
  },
  Mutation: {
    addMessage(root, { message }) {
      let entry = JSON.stringify({ id: messages.length, message: message });
      messages.push(entry);
      pubsub.publish('newMessage', { entry: entry });
      return messages;
    },
  },
  Subscription: {
    newMessage: {
      resolve: (message) => {
        return message.entry;
      },
      subscribe: () => pubsub.asyncIterator('newMessage'),
    },
  },
};

const app = express();

const PORT = 4000;

const server = new ApolloServer({
  typeDefs,
  resolvers,
  subscriptions: {
    onConnect: () => console.log('Connected to websocket'),
  }
});

server.applyMiddleware({ app })

const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);

httpServer.listen(PORT, () => {
  console.log(`???? Server ready at http://localhost:${PORT}${server.graphqlPath}`)
  console.log(`???? Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
})

其他端点工作正常,但无法创建 WebSocket。据我了解,我不应该使用不同的服务器或端口(请参阅https://www.ably.io/concepts/websockets)。我已经修改了SubsciptionServer,但这应该由installSubscriptionHandlers (here's the code) 处理。

【问题讨论】:

    标签: javascript graphql apollo-server graphql-subscriptions


    【解决方案1】:

    事实证明,Firefox 的 websockets 存在问题(请参阅this bug report,即使在假定的修复之后也重新出现)。

    在 Firefox 中,它在启动一个新颖的浏览器后直接运行,但在一些热重载后它停止运行。以下内容有助于重新开始,但不会解决重新加载问题:

    const wsLink = new WebSocketLink({
      uri: SUBSCRIPTION_URI,
      options: {
        reconnect: true,
        timeout: 20000,
        lazy: true,
      },
    });
    
    window.addEventListener('beforeunload', () => {
      // @ts-ignore - the function is private in typescript
      wsLink.subscriptionClient.close();
    });
    

    我认为这个错误与这个 SO 问题有关:"websocket was interrupted while page is loading" on Firefox for Socket.io

    如果您想测试不同的解决方案,我创建了一个示例 repo:https://github.com/gforge/subscription_example,它既可以单独使用,也可以与 Docker 容器一起使用。

    【讨论】:

      【解决方案2】:

      很多时间过去了,现在我遇到了同样的问题,我找到了解决方案。

      import { createServer } from 'http';
      const app = express();
      const server = new ApolloServer({});
      server.applyMiddleware({ app });
      const httpServer = createServer(app);
      server.installSubscriptionHandlers(httpServer);
      server.listen()
      

      为我工作

      【讨论】:

      • 在最后一行,我必须使用httpServer.listen() 而不是server.listen()。也许这是答案作者的错字?
      猜你喜欢
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 2018-01-13
      • 1970-01-01
      • 2016-12-14
      • 2018-09-20
      相关资源
      最近更新 更多