繁体   English   中英

订阅不适用于 Apollo Server Express

[英]Subscriptions not working on Apollo Server Express

我想用 express 添加对我已经工作的 apollo 服务器的订阅,但我什至无法连接到操场上。 我从操场上得到这个错误

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

从 firefox 一个 chrome 我得到类似的错误

Firefox can’t establish a connection to the server at ws://localhost:4000/graphql

这是我的 app.js 我的主文件。

const express = require('express');
const mongoose = require('mongoose');
const { ApolloServer } = require('apollo-server-express');

const cors = require('cors');
const session = require('express-session');
const Keycloak = require('keycloak-connect');

const { typeDefs } = require('./graphql/Schema');
const { resolvers } = require('./graphql/Resolvers');
const { userTypeDefs, userResolvers } = require('./graphql/User');
const { campusTypeDefs, campusResolvers } = require('./graphql/Campus');
const { profileTypeDefs, profileResolvers } = require('./graphql/Profile');
const { notificationTypeDefs, notificationResolvers } = require('./graphql/Notification');
const { rideTypeDefs, rideResolvers } = require('./graphql/Ride');

const app = express();
app.use(i18n.init);
const keycloak = new Keycloak({
  memoryStore
}, 'keycloak.json');

app.use('/graphql', keycloak.middleware());

const server = new ApolloServer({
  typeDefs: [KeycloakTypeDefs, typeDefs, rideTypeDefs, userTypeDefs, campusTypeDefs, profileTypeDefs, notificationTypeDefs],
  schemaDirectives: KeycloakSchemaDirectives,
  cors: cors(corsOptions),
  resolvers: [resolvers, rideResolvers, userResolvers, campusResolvers, profileResolvers, notificationResolvers],
  context: ({ req, connection }) => {
    console.log(connection);
    return { kauth: new KeycloakContext({ req }) };
  },
  subscriptions: {
    onConnect: async (connectionParams, webSocket) => {
      console.log("xxx");
      console.log(connectionParams);
      if (connectionParams.authToken) {
        return validateToken(connectionParams.authToken)
          .then(findUser(connectionParams.authToken))
          .then(user => {
            return {
              currentUser: user,
            };
          });
      }

      throw new Error('Missing auth token!');
    },
  }
});

server.applyMiddleware({ app });
server.installSubscriptionHandlers(app);

mongoose.connect(
  'mongodb://deaventon:mapache@localhost:27017/deaventon')
  .then(result => {
    app.listen(4000);
  })
  .catch(err => console.log(err));

根据一些例子 server.installSubscriptionHandlers 应该是足够的,在其他一些情况下他们不使用它。 但我认为它与 apollo-server-express 有关,通常使用 apollo-server-express 的示例使用它。 当我对连接执行console.log() 时,我得到一个未定义的结果,即使来自套接字连接的请求也是如此。 我可以看到 req 或 socket 请求。 我从来没有在订阅中得到任何东西。onConnect function,它显然没有被调用,因为它从不建立连接。 如果我从上下文到 req var 执行 console.log,我会得到类似这样的东西

IncomingMessage {
  _readableState: ReadableState {
    objectMode: false,
    highWaterMark: 16384,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: null,
    pipesCount: 0,
    flowing: null,
    ended: true,
    endEmitted: false,
    reading: false,
    sync: true,
    needReadable: false,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    emitClose: true,
    autoDestroy: false,
    destroyed: false,
    defaultEncoding: 'utf8',
    awaitDrain: 0,
    readingMore: true,
    decoder: null,
    encoding: null,
    [Symbol(kPaused)]: null
  },
  readable: true,
  _events: [Object: null prototype] {
    end: [Function: resetHeadersTimeoutOnReqEnd]
  },
  _eventsCount: 1,
  _maxListeners: undefined,
  socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: null,
      pipesCount: 0,
      flowing: true,

似乎它甚至没有验证订阅。

您必须通过另一台installSubscriptionHandlers服务器来安装 SubscriptionHandlers 而不是 express并监听它。 这是您的代码简化和工作:

const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const { gql } = require('apollo-server');
const http = require('http');

const app = express();

/* I have removed your middleware to simplify example 
 but you can observe that middleware is still used */
app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
});


const resolvers = {
  Query: { test: () => {} },
  Subscription: { test: () => {} },
  Mutation: { test: () => {} },
};

const typeDefs = gql`
  type Query {
    test(id: ID!): ID
  }

  type Mutation {
    test(id: ID!): ID
  }

  type Subscription {
    test(id: ID!): ID
  }
`;

const server = new ApolloServer({
  typeDefs: [typeDefs],
  resolvers: [resolvers],
  context: ({ req, connection }) => {
    console.log(connection);
    return {};
  },
  subscriptions: {
    onConnect: async (connectionParams, webSocket) => {
      console.log('xxx');
      console.log(connectionParams);
    },
  },
});

const httpServer = http.createServer(app);

server.applyMiddleware({ app });
server.installSubscriptionHandlers(httpServer);

const port = 4003;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM