2

以前我的 apollo 设置一直在监听订阅,直到我添加到 socket.io 中,现在我的客户端设置不再监听新数据。根据我使用 graphql 游乐场的测试,我的服务器代码似乎没问题。

在我的浏览器控制台中,我收到以下错误消息

client.js:652 WebSocket 连接到“ws://localhost:4000/”失败:WebSocket 握手期间出错:意外响应代码:400

我的客户端设置使用阿波罗订阅似乎存在一些问题。

欣赏任何指针?提前致谢

import { ApolloClient } from "apollo-client";
import { onError } from "apollo-link-error";
import { ApolloLink, split } from "apollo-link";
import { createUploadLink } from "apollo-upload-client";
import gql from "graphql-tag";
import { withClientState } from "apollo-link-state";
import { InMemoryCache } from "apollo-cache-inmemory";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import { setContext } from "apollo-link-context";

    const cache = new InMemoryCache();

    const defaultState = {
      currentGame: {
        __typename: "currentGame",
        teamAScore: 0,
        teamBScore: 0,
        teamAName: "EAGLES",
        teamBName: "LOL"
      }
    };

    const stateLink = withClientState({
      cache,
      defaults: defaultState,
      resolvers: {
        Mutation: {
          updateGame: (_, { index, value }, { cache }) => {
            const query = gql`
              query GetCurrentGame {
                currentGame @client {
                  teamAScore
                  teamBScore
                  teamAName
                  teamBName
                }
              }
            `;
            const previous = cache.readQuery({ query });
            const data = {
              currentGame: {
                ...previous.currentGame,
                [index]: value
              }
            };
            cache.writeQuery({ query, data });
            return null;
          },
          resetCurrentGame: (_, d, { cache }) => {
            cache.writeData({ data: defaultState });
          }
        }
      }
    });

    const host = "http://localhost:4000";

    // httpLink
    const httpLink = createUploadLink({
      uri: `${host}/graphql`,
      credentials: "same-origin"
    });

    // wsLink
    const wsLink = new WebSocketLink({
      uri: `ws://localhost:4000/`,
      options: {
        reconnect: true
      }
    });

    // using the ability to split links, you can send data to each link
    // depending on what kind of operation is being sent
    const webLink = split(
      // split based on operation type
      ({ query }) => {
        const { kind, operation } = getMainDefinition(query);
        return kind === "OperationDefinition" && operation === "subscription";
      },
      wsLink,
      httpLink
    );

    // authMiddleware
    const authLink = setContext(async (req, { headers }) => {
      //  const token = await AsyncStorage.getItem("@token");
      const token = "";

      return {
        headers: {
          ...headers,
          authorization: token ? `${token}` : ""
        }
      };
    });

    const errorLink = onError(({ networkError, graphQLErrors }) => {
      if (graphQLErrors) {
        graphQLErrors.map(({ message, locations, path }) =>
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
          )
        );
      }
      if (networkError) console.log(`[Network error]: ${networkError}`);
    });

    export const client = new ApolloClient({
      link: ApolloLink.from([authLink, stateLink, errorLink, webLink]),
      cache
    });

如果需要,我的服务器端代码

//! Using Apollo Server Express
const app = express();
const path = "/graphql";
const schema = genSchema();

export const startServer = async () => {
  const server = new ApolloServer({
    schema,
    context: ({ req }: any) => ({
      req,
      pubsub,
      userLoader: userLoader()
    })
  });

  app.use(cors());

  app.use(authMiddleware);

  app.use("/images", express.static("images"));

  app.use(
    "graphql",
    graphqlUploadExpress({
      uploadDir: "/",
      maxFileSize: 100000000,
      maxFiles: 10
    }),
    graphqlHTTP({ schema }) as any
  );

  server.applyMiddleware({ app, path });

  //! Added Subscription Handler
  const httpServer = createServer(app);
  server.installSubscriptionHandlers(httpServer);

  const port = process.env.PORT || 4000;

  await createConnection();

  await httpServer.listen({
    port
  });

  console.log(`Server is running on localhost:${port}${server.graphqlPath}`);
};
4

1 回答 1

1

纠正。我的客户端 apollo 设置应该指向 ws://localhost:4000/ graphql而不仅仅是 ws://localhost:4000/

// wsLink
const wsLink = new WebSocketLink({
  uri: `ws://localhost:4000/graphql`,
  options: {
    reconnect: true
  }
});
于 2018-12-02T10:17:40.303 回答