Apollo 2.x 客户端和服务器设置:WebSocket 握手期间出错?
Posted
技术标签:
【中文标题】Apollo 2.x 客户端和服务器设置:WebSocket 握手期间出错?【英文标题】:Apollo 2.x Client and Server Setup: Error during WebSocket handshake? 【发布时间】:2018-09-10 11:36:10 【问题描述】:我已经让 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】:首先想到的是:
您的服务器侦听端口 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
);
【讨论】:
以上是关于Apollo 2.x 客户端和服务器设置:WebSocket 握手期间出错?的主要内容,如果未能解决你的问题,请参考以下文章
Meteor/s-s-r/Apollo 客户端 - 尝试使用 Apollo 设置 s-s-r 并没有找到 fetch
设置 Redis cookie 时,Apollo 客户端未连接到服务器