阿波罗2.x客户端和服务器设置:WebSocket握手期间出现错误?

4
我已经成功使用Apollo 2.x进行查询和变更。现在我正在为订阅实现客户端和服务器设置。但是,我在浏览器控制台中遇到了以下错误信息:

VM3719:164 WebSocket连接到'ws://localhost:3200/'失败: WebSocket握手期间发生错误:意外响应代码:400


通过研究众多可用资源,我感觉我的代码非常接近正确,但我尚未解决此错误。

以下是我的当前设置代码:

客户端
import React from "react";
import { Meteor } from "meteor/meteor";
import { render } from "react-dom";
import { ApolloProvider } from "react-apollo";
import { ApolloLink, from } from "apollo-link";
import { ApolloClient } from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { onError } from 'apollo-link-error';
import { split } from 'apollo-link';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';

import App from "../../ui/App";

// Create an http link:
const httpLink = new HttpLink({
    uri: Meteor.absoluteUrl("graphql"),
    credentials: 'same-origin'
})

// Create a WebSocket link:
const wsLink = new WebSocketLink({
    uri: `ws://localhost:3200/`,
    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 splitLink = split(
    // split based on operation type
    ({ query }) => {
        const { kind, operation } = getMainDefinition(query);
        return kind === 'OperationDefinition' && operation === 'subscription';
    },
    wsLink,
    httpLink,
);

const authLink = new ApolloLink((operation, forward) => {
  const token = Accounts._storedLoginToken();
  operation.setContext(() => ({
    headers: {
      "meteor-login-token": token
    }
  }));
  return forward(operation);
});

const client = new ApolloClient({
    link: ApolloLink.from([
        onError(({ graphQLErrors, networkError }) => {
            if (graphQLErrors)
                graphQLErrors.map(({ message, locations, path }) =>
                    console.log(
                        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
                    ),
                );
            if (networkError) console.log(`[Network error]: ${networkError}`);
        }),
        authLink,
        splitLink
    ]),
    cache: new InMemoryCache()
});


const ApolloApp = () => (
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>
);

Meteor.startup(() => {
  render(<ApolloApp />, document.getElementById("app"));
});

服务器

import { createApolloServer } from "meteor/apollo";
import { makeExecutableSchema } from "graphql-tools";
import merge from "lodash/merge";

import GoalsSchema from "../../api/goals/Goal.graphql";
import GoalsResolvers from "../../api/goals/resolvers";
import ResolutionsSchema from "../../api/resolutions/Resolutions.graphql";
import ResolutionsResolvers from "../../api/resolutions/resolvers";
import UsersSchema from "../../api/users/User.graphql";
import UsersResolvers from "../../api/users/resolvers";
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { execute, subscribe } from 'graphql';

const typeDefs = [GoalsSchema, ResolutionsSchema, UsersSchema];

const resolvers = merge(GoalsResolvers, ResolutionsResolvers, UsersResolvers);

const schema = makeExecutableSchema({
  typeDefs,
  resolvers
});

createApolloServer({ schema });

const WS_PORT = 3200;

// Create WebSocket listener server
const websocketServer = createServer((request, response) => {
    response.writeHead(404);
    response.end();
});

// Bind it to port and start listening
websocketServer.listen(WS_PORT, () => console.log(
    `Websocket Server is now running on http://localhost:${WS_PORT}`
));

const subscriptionServer = SubscriptionServer.create(
    {
        schema,
        execute,
        subscribe,
    },
    {
        server: websocketServer,
        path: '/graphql',
    },
);

我该如何纠正这个错误?

非常感谢大家提供的任何信息。

1个回答

1

首先要考虑的是:

您的服务器监听端口3200,并使用路由graphql

const subscriptionServer = SubscriptionServer.create(
    {
        schema,
        execute,
        subscribe,
    },
    {
        server: websocketServer,
        path: '/graphql', // used url route
    },
);

所以您的客户端websocket链接必须使用正确的路由来连接单个graphql端点。更改为以下内容:

// Create a WebSocket link:
const wsLink = new WebSocketLink({
    uri: `ws://localhost:3200/graphql`, // correct websocket url
    options: {
        reconnect: true
    }
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接