订阅未使用ApolloServer连接

Max*_*don 6 javascript graphql apollo-server graphql-subscriptions

我正在尝试建立订阅并使用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."
}
Run Code Online (Sandbox Code Playgroud)

由于我的应用程序中有休息端点,因此我需要表达自己的观点,但是我无法从下面的运行中获得最少的示例:

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}`)
})
Run Code Online (Sandbox Code Playgroud)

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

Max*_*don 2

事实证明,Firefox 在 websockets 方面存在问题(请参阅此错误报告,即使在假定的修复之后,该报告仍然重新出现)。

在 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();
});
Run Code Online (Sandbox Code Playgroud)

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

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