我正在对Apollo GraphQL订阅使用React,我可以在Apollo Playground上收到更新,但不能在Client上收到更新。这是在阿波罗游乐场上的回应:
Graphql服务器位于http://localhost:4000/
上,订阅位于ws:// localhost:4000 / graphql上。但是,它可以在操场上运行,但不能在客户端运行。我已经以这种方式设置了Apollo客户端,以接收来自服务器的更新:
import ApolloClient from 'apollo-boost';
import { WebSocketLink } from 'apollo-link-ws';
import { HttpLink } from 'apollo-link-http';
import { split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
export const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`,
options: {
reconnect: false
}
});
export const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
export const client = new ApolloClient({
uri: 'http://localhost:4000/',
});
我认为我使用过useSubscriptions
:
const MESSAGE_SENT_SUBSCRIPTION = gql`subscription {
messageSent {
id
message
}
}`
const {data: newMessage, loading: newMessageLoading} = useSubscription(MESSAGE_SENT_SUBSCRIPTION, {});
在渲染时,我使用了:
{!newMessageLoading && JSON.stringify(newMessage)}
但是从客户端,它没有收到更新,但是我确定它与Graphql WebSockets服务器连接。
服务器端:
let database = require("./src/database.js")
let schema = require("./src/schema.js");
let resolvers = require("./src/resolvers.js");
let {ApolloServer} = require("apollo-server");
// The ApolloServer constructor requires two parameters: your schema
// definition and your set of resolvers.
const server = new ApolloServer({
typeDefs: schema,
resolvers: resolvers,
context: {
database
}
});
// The `listen` method launches a web server.
server.listen().then(({ url,subscriptionsUrl ,subscriptionsPath}) => {
console.log(`? Server ready at ${url}`);
console.log(`realtime here at ${subscriptionsUrl} and path ${subscriptionsPath}`)
});
我在这里做错什么,有没有遇到这种问题的人?
答案 0 :(得分:1)
我必须从apollo-client
导入ApolloClient。这是客户端的工作配置:
import ApolloClient from 'apollo-client';
import { WebSocketLink } from 'apollo-link-ws';
import { HttpLink } from 'apollo-link-http';
import { split } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { getMainDefinition } from 'apollo-utilities';
export const httpLink = new HttpLink({
uri: "http://localhost:4000/graphql", // use https for secure endpoint
});
// Create a WebSocket link:
export const wsLink = new WebSocketLink({
uri: "ws://localhost:4000/subscriptions", // use wss for a secure endpoint
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
export const link = split(
// split based on operation type
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink,
);
// Instantiate client
export const client = new ApolloClient({
link,
uri: "http://localhost:4000/graphql",
cache: new InMemoryCache()
})
答案 1 :(得分:0)
您需要将拆分的链接传递给ApolloClient构造函数。 尝试像这样(客户端)通过它:
import ApolloClient from 'apollo-boost';
import { WebSocketLink } from 'apollo-link-ws';
import { HttpLink } from 'apollo-link-http';
import { split } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { getMainDefinition } from 'apollo-utilities';
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
export const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/subscriptions`,
options: {
reconnect: false
}
});
export const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
export const graphqlServer = 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}`);
}
}),
link // YOUR LINK (NOW MATCHING YOUR CODE)
])
});
和服务器端:
...
const server = new ApolloServer({
typeDefs: schema,
resolvers: resolvers,
subscriptions: {
path: '/subscriptions'
},
context: {
database
}
});
...
请注意,/subscriptions
也传递给了ApolloClient