2017-04-06 34 views
1

私は、クライアントとサーバーの両方でGraphqlサブスクリプションを設定するためにApolloのドキュメントに従っていますが、90%ですが、セットアップ方法を理解できません突然変異が発生するたびにサーバーが新しいデータをクライアントにプッシュするように、突然変異をそのチャンネルに接続する方法について説明します。 (コンテンツに関しては、トピックを投稿したり他の人がコメントを投稿するRedditクローンを作成していますので、「トピック」や「トピックリスト」と表示されたときは投稿と考えてください)Express-GraphQLとReact-Apolloを使用したGraphQLサブスクリプション

これまでのところ、サブスクリプションのための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 
}); 

サブスクリプション用にバックエンドを設定しました。私は、端末にログインし、「WebSocketの接続確立」メッセージが表示されますので、私はこれらが成功している知っている

//=========================================================== 
//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!'); 
}) 

:ここに私のserver.jsファイルです。

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

私のコンポーネントを反応させるのでは、私は成功したアポロの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) 
     }) 

     } //... 

そしてI私の端末に "クライアントが購読されました"というメッセージが記録されるようにしてください。しかし、これは私が立ち往生している場所です。 SubscriptionManagerのSetupFunctionについて読んだことがありますが、Apolloのドキュメントには含まれていません。そして、私は誰かが新しいトピックを追加するたびにTopicListにポップアップするように、このサブスクリプションに 'createTopic'突然変異をマップする方法を見つけることができません。

私はこれが本当に長いことを認識していますが、私は次のステップが何であるか把握するために私の髪を引き出しています。どんな助けでも大歓迎です!!読んでくれてありがとう!

答えて

0

はい、セットアップ機能がありません。このリンクGraphQL subscription docuまたはexampleをご覧ください。

どのように動作する必要がありますか: 変更されたデータを公開するチャネルが最初に必要です。サブスクリプションでargs: {repoFullName: {type: GraphQLString}}引数の必要性を参照してください

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 
 
     }, 
 
     }, 
 
    }), 
 
    }, 
 
});

そしてここに:あなたのケースでは、このようになります。 "repoName"に応じてサブスクリプションをフィルタリングする場合。つまり、引数として "repoName"を持つサブスクリプションを持つクライアントだけが更新を取得することを意味します。

次に、pubsub.publish関数を呼び出す場所が必要です。あなたのケースでは、追加トピックの突然変異が通過した後。

... 
 

 
const topic = new Topic(/* args */); 
 
topic.save((error, topic) => { 
 
    if (!error) { 
 
    pubsub.publish("topicAddedChannel", topic); 
 
    } 
 
    ... 
 
}); 
 

 

 
....

+0

おかげLocco0_0:このようになります!しかし、たとえ私は新しいコメントを追加しようとする前に、私はコンソールにこのエラーが表示されます。 キャッチされない例外TypeErrorを:だけでなく、WebSocket.client.onmessage で 未定義のプロパティ「ハンドラ」を読み込めません: 無効paramsが返さfromSubscribe!戻り値はオブジェクトでなければなりません! ここで私のaddTopicの突然変異は(コード化されているので、ここでは文字の制限に合わせることができませんでした):[link](https:// codepen。 io/bfitty/pen/jBoXda) トピックを追加することはできますが、通常のやり方でページをリフレッシュしてリストに表示する必要がありますか考えていますか? –

+0

サブスクリプションの定義はうまくいきます。 TopicType'が定義されていますか? サブスクリプションに渡す引数がないので、引数argsを削除することができます。 id } } ; ' 最初のエラーは本当にわかりませんが、サブスクリプションクエリがロードされているかどうかを確認するには、サブコンポーネントを' componentWillReceiveProps(newProps) '関数に追加してください。 –

+0

そして私はちょうどあなたの設定'新しいpubsub()'ここでは、subscriptionManagerに追加したものと同じものを使用する必要があります –

関連する問題