Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用Express GraphQL和React Apollo订阅GraphQL_Reactjs_Express_Publish Subscribe_Graphql_Apollo - Fatal编程技术网

Reactjs 使用Express GraphQL和React Apollo订阅GraphQL

Reactjs 使用Express GraphQL和React Apollo订阅GraphQL,reactjs,express,publish-subscribe,graphql,apollo,Reactjs,Express,Publish Subscribe,Graphql,Apollo,我遵循Apollo的文档在客户端和服务器上都设置了GraphQL订阅,虽然我有90%在那里,但我不知道如何设置订阅通道以及如何将突变连接到这些通道,以便每当发生突变时,服务器都将新数据推送到客户端。(对于内容,我正在制作一个Reddit克隆,人们在其中发布主题,其他人对此进行评论。因此,当您看到“主题”或“主题列表”时,请将其视为帖子。) 到目前为止,我已成功为订阅设置了Apollo客户端: const wsClient = new SubscriptionClient('ws://localh

我遵循Apollo的文档在客户端和服务器上都设置了GraphQL订阅,虽然我有90%在那里,但我不知道如何设置订阅通道以及如何将突变连接到这些通道,以便每当发生突变时,服务器都将新数据推送到客户端。(对于内容,我正在制作一个Reddit克隆,人们在其中发布主题,其他人对此进行评论。因此,当您看到“主题”或“主题列表”时,请将其视为帖子。)

到目前为止,我已成功为订阅设置了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连接已建立”消息

接下来是实际订阅-我创建了一个订阅模式类型(就像查询和突变):

并将其合并到我的根模式中。因此,当我签出GraphiQL时,我看到:这个订阅在Docs侧菜单中可用

在我的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,但是Apollo的文档中没有包含它。我找不到如何将“createTopic”变异映射到这个订阅,这样每当有人添加新主题时,它就会在TopicList中弹出


我意识到这真的很长,但我一直在想下一步该怎么做。任何帮助都将不胜感激!!谢谢你的阅读

是,您缺少设置功能。你可以看看这个链接或者这个

工作原理: 首先,您需要发布更改数据的通道。在您的情况下,它可能如下所示:

const manager=new sub.SubscriptionManager({
模式,
pubSub,
设置功能:{
topicAdded:(选项,参数)=>({//graphQL订阅的名称
topicAddedChannel:{//pubsub发布标记的名称
过滤器:(主题)=>{
console.log(topic);//如果有订阅的客户端,则应始终显示新主题
return true;//您可能需要添加筛选器。可能是针对来宾用户或其他用户
},
},
}),
},

});谢谢你!但是,即使在我尝试添加新注释之前,我在控制台中也会遇到以下错误:uncaughtypeerror:无法读取WebSocket.client.onmessage中未定义的属性“handler”,以及:onSubscribe返回的参数无效!返回值必须是一个对象!“为了更多的参考,这里是我的addTopic变体(在一个代码笔中,因为我不能在这里设置字符限制):我仍然可以添加主题,但我必须执行常规操作并刷新页面以使其显示在列表上。有什么想法吗?订阅定义看起来不错。
TopicType
是否已定义?在您的情况下,您可以删除args参数,因为您没有要传递给订阅的参数。因此可以删除它这里
const TOPICS\u SUBSCRIPTION=gql SUBSCRIPTION OnTopicAdded{topicAdded{id};
我并不清楚第一个错误,但是您可以在
组件willreceiveprops(newProps)中添加订阅
函数,然后检查订阅查询是否已加载,我刚才在代码链接中看到,您正在设置一个
新的pubsub()
。在这里,您必须使用添加到subscriptionManager中的相同内容
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)
        })

      } //...