Apollo 订阅未在客户端监听新数据
Posted
技术标签:
【中文标题】Apollo 订阅未在客户端监听新数据【英文标题】:Apollo Subscriptions not listening to new data on client 【发布时间】:2019-05-03 21:19:59 【问题描述】:以前我的 apollo 设置一直在监听订阅,直到我添加到 socket.io 中,现在我的客户端设置不再监听新数据。根据我使用 graphql 游乐场的测试,我的服务器代码似乎没问题。
在我的浏览器控制台中,我收到以下错误消息
client.js:652 WebSocket 连接到“ws://localhost:4000/”失败:WebSocket 握手期间出错:意外响应代码:400
我的客户端设置似乎存在一些问题,以使用 apollo 订阅。
欣赏任何指针?提前致谢
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`);
;
【问题讨论】:
【参考方案1】:已纠正。我的客户端 apollo 设置应该指向 ws://localhost:4000/graphql 而不仅仅是 ws://localhost:4000/
// wsLink
const wsLink = new WebSocketLink(
uri: `ws://localhost:4000/graphql`,
options:
reconnect: true
);
【讨论】:
以上是关于Apollo 订阅未在客户端监听新数据的主要内容,如果未能解决你的问题,请参考以下文章
突变后使用订阅和更新创建重复节点 - 使用 Apollo 客户端
Apollo 客户端未在 Nextjs Lamda 中发送 JWT 不记名令牌