我一直按照阿波罗的文档在客户端和服务器端建立GraphQL订阅,虽然我有90%的经验,但我不知道如何建立订阅通道,以及如何将突变连接到这些通道,以便每当突变发生时,服务器会将新数据推送到客户端。(对于内容,我正在制作一个Reddit克隆,人们可以在其中发布主题,其他人可以对其进行评论。因此,当您看到“主题”或"TopicList“时,请将其视为帖子。)
到目前为止,我已经成功地为订阅设置了Apollo客户端:
const wsClient = new SubscriptionClient('ws://localhost:3001/subscriptions', {
reconnect: true
});
const networkInterface = createNetworkInterface({
uri: '/graphql',
opts: {
credentials: 'same-origin'
}
});
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient,
);
const client = new ApolloClient({
networkInterface: networkInterfaceWithSubscriptions,
dataIdFromObject: o => o.id
});我也为订阅设置了我的后端。这是我的server.js文件:
//===========================================================
//Subscription Managaer
//===========================================================
const pubsub = new PubSub();
const subscriptionManager = new SubscriptionManager({
schema: schema,
pubsub: pubsub
});
//=====================================
//WebSocket + Express Server
//=====================================
const server = createServer(app);
//setup listening port
server.listen(3001, ()=>{
new SubscriptionServer(
{
subscriptionManager: subscriptionManager,
onConnect: (connectionParams, webSocket) => {
console.log('Websocket connection established');
},
onSubscribe: (message, params, webSocket) => {
console.log("The client has been subscribed", message, params);
},
onUnsubsribe: (webSocket) => {
console.log("Now unsubscribed");
},
onDisconnect: (webSocket) => {
console.log('Now disconnected');
}
},
{
server: server,
path: '/subscriptions',
});
console.log('Server is hot my man!');
})我知道这些操作是成功的,因为我的终端中记录了"Websocket connection established“消息。
接下来是实际的订阅--我已经创建了一个订阅模式类型(就像查询和突变一样):
const SubscriptionType = new GraphQLObjectType({
name: 'Subscription',
fields: () => ({
topicAdded: {
type: TopicType,
args: {repoFullName: {type: GraphQLString}}, //I don't understand what repoFullName is - I was trying to follow the Apollo docs, but they never specified that
resolve(parentValue, args){
return parentValue;
}
}
})
});
module.exports = SubscriptionType;并将其合并到我的根模式中。因此,当我查看GraphiQL时,我看到:此订阅在文档侧菜单My GraphiQIL UI showing the subscriptionSchema successfully中可用
在我的React组件中,我使用Apollo的subscribeToMore方法成功地‘订阅’了它:
const TOPICS_SUBSCRIPTION = gql`
subscription OnTopicAdded($repoFullName: String){
topicAdded(repoFullName: $repoFullName){
id
}
}
`;
class TopicList extends Component {
componentDidMount() {
this.createMessageSubscription = this.props.data.subscribeToMore({
document: TOPICS_SUBSCRIPTION,
// updateQuery: (previousState, {subscriptionData}) => {
// const newTopic = subscriptionData.data.Topic.node
// const topics = previousState.findTopics.concat([newTopic])
// return {
// findTopics: topics
// }
// },
onError: (err) => console.error(err)
})
} //...我在我的终端上收到了“客户已被订阅”的消息。但这就是我被困住的地方。我读到过SubscriptionManager的SetupFunction,但阿波罗的文档中并没有提到。我找不到如何将'createTopic‘突变映射到这个订阅中,这样每当有人添加新主题时,它就会在TopicList中弹出。
我知道这真的很漫长,但我一直在绞尽脑汁想知道下一步该做什么。任何帮助都将不胜感激!感谢您的阅读!
发布于 2017-04-07 03:37:46
是的,你错过了设置功能。你可以看看这个链接GraphQL subscription docu或者这个example。
它的工作原理:首先,您需要在其中发布更改的数据的通道。在您的示例中,它可能如下所示:
const manager = new sub.SubscriptionManager({
schema,
pubSub,
setupFunctions: {
topicAdded: (options, args) => ({ // name of your graphQL subscription
topicAddedChannel: { // name of your pubsub publish-tag
filter: (topic) => {
console.log(topic); //should always show you the new topic if there is a subscribed client
return true; // You might want to add a filter. Maybe for guest users or so
},
},
}),
},
});
在这里,您可以看到订阅中需要使用args: {repoFullName: {type: GraphQLString}}参数。如果您想根据repoName过滤订阅。这意味着只有订阅了参数为"repoName“的客户端才能获得更新。
接下来,您需要一个调用pubsub.publish函数的地方。在您的情况下,添加主题突变已通过。可能如下所示:
...
const topic = new Topic(/* args */);
topic.save((error, topic) => {
if (!error) {
pubsub.publish("topicAddedChannel", topic);
}
...
});
....
https://stackoverflow.com/questions/43259469
复制相似问题