2017-04-06 10 views
1

저는 클라이언트와 서버 모두에서 GraphQL 가입 설정을 위해 Apollo의 문서를 읽었습니다. 저는 90 %이지만 설정 방법을 알 수 없습니다 구독 채널 및 이러한 채널에 변이를 연결하여 변이가 발생할 때마다 서버가 새 데이터를 클라이언트에 푸시하도록하는 방법에 대해 설명합니다. (콘텐츠의 경우 사람들이 주제를 게시하고 다른 사람들이 의견을 게시하는 Reddit 복제본을 만들고 있으므로 "주제"또는 "주제 목록"을 볼 때 게시물로 생각하십시오.)Express-GraphQL 및 React-Apollo가있는 GraphQL Subscription

지금까지, 구독을위한 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 
}); 

그리고 서브 스크립 션을위한 백엔드도 설정했습니다. 내 단말기에 기록 된 "웹 소켓 연결 설정"메시지가 있기 때문에, 나는이 성공적으로 알고

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

     } //... 

그리고 난을 내 "클라이언트가 가입되었습니다."라는 메시지가 내 단말기에 기록됩니다. 그러나 이것은 내가 붙어있는 곳이다. SubscriptionManager에 대한 SetupFunction에 대해 읽었지만 Apollo의 문서에는 포함되어 있지 않습니다. 그리고 누군가가 새로운 주제를 추가 할 때마다 TopicList에서 팝업되도록 createTopic 변이를이 구독에 매핑하는 방법을 찾을 수 없습니다.

나는 이것이 정말로 길다는 것을 알고 있지만, 나는 다음 단계가 무엇인지 알아 내기 위해 머리카락을 꺼내왔다. 어떤 도움을 많이 주시면 감사하겠습니다! 읽어 주셔서 감사합니다!

답변

0

예 설정 기능이 없습니다. 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); 
 
    } 
 
    ... 
 
}); 
 

 

 
....

+0

감사 Locco0_0을!나는 새로운 코멘트를 추가하려고도 전에, 나는 콘솔에서이 오류를 얻을 : catch되지 않은 형식 오류가 : WebSocket.client.onmessage 뿐만 아니라에서 정의되지 않은 의 특성 '핸들러'를 읽을 수 없습니다 : 잘못된 PARAMS 반환 fromSubscribe! 반환 값은 객체 여야합니다! " 더 많은 참조를 위해 여기에 내 addTopic 변이가 있습니다 (코드 한계로 여기에 맞지 않아서 codepen에 있습니다) : [link] (https : // codepen. io/bfitty/pen/jBoXda) 주제를 추가 할 수는 있지만 목록을 표시하려면 페이지를 새로 고쳐야합니다. 어떤 생각? –

+0

구독 정의가 좋았습니다. TopicType'이 정의 되었습니까? 구독에 전달할 인수가 없으므로 args 인수를 제거 할 수 있습니다. 여기에서 제거 할 수 있습니다. 'const TOPICS_SUBSCRIPTION = gql 구독 OnTopicAdded { topicAdded { id } } ;' 첫 번째 오류는 분명하지 않지만 'componentWillReceiveProps (newProps)'함수에 구독을 추가하고 구독 쿼리가로드되었는지 확인하십시오 –

+0

그리고 코드 링크에서 설정 한 내용을 확인할 수 있습니다 '새로운 pubsub()'. 여기에서는 subscriptionManager에 추가 한 것과 동일한 것을 사용해야합니다. –