当前位置: 首页 > 知识库问答 >
问题:

使用Express GraphQL和React-GraphQL订阅Apollo

燕建中
2023-03-14

我按照Apollo的文档在客户端和服务器上设置GraphQL订阅,虽然我已经完成了90%,但我不知道如何设置订阅通道以及如何将突变连接到这些通道,以便每当突变发生时,服务器都会将新html" target="_blank">数据推送到客户端。(对于内容,我正在制作一个Reddit克隆,人们可以在其中发布主题,其他人可以对其发表评论。所以当你看到“Topics”或“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
});

我还为订阅设置了后端。这是我的服务器。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连接已建立”消息。

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

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时,我看到:这个订阅在Docs侧菜单中可用,我的GraphiQIL UI成功地显示了订阅模式

在我的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中弹出。

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

共有1个答案

年业
2023-03-14

是的,您缺少设置功能。您可以查看此链接GraphQL订阅文档或此示例。

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

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
        },
      },
    }),
  },
});
 类似资料:
  • 我在Apollo中的GraphQL订阅遇到了麻烦。我想订阅关于主题的添加“透视图”(基本上是在帖子上添加评论),我很确定我已经正确地设置了服务器。客户才是给我带来麻烦的人。(如果这个问题看起来很熟悉,我以前问过它,以为我得到了答案,但没有去)。下面是我的订阅模式: 我也正确地连接了客户端,因为在我的终端中,我看到了“WebSocket connection Selected”消息。我被难倒的部分是

  • 我正在学习如何使用gem在Rails应用程序中实现GraphQL API。我不清楚GraphQL订阅的用例。 我不清楚GraphQL订阅和ActionCable之间的区别。 假设我有一个从GraphQL API获取数据的移动应用程序。 我是否可以直接使用ActionCable将更改发布到移动客户端?如果是,那么为什么要使用GraphQL订阅呢?

  • 如何使用 Graphql SPQR 库实现 GraphQL 的订阅功能?

  • 在客户端使用apollo-link,在服务器上使用apollo-server-express中的PubSub。在与GraphQL API交谈的摩卡测试中得到奇怪的结果: 摩卡: 服务器: 以下是我(从测试中)看到的情况: 收到的数据:1545013826838,{“errors”:[{“message”:“对于不可为null的字段订阅,无法返回null。info。”,。。。 (来自服务器): 订阅

  • 我尝试使用Vertx HttpClient/WebClient来使用GraphQL订阅,但没有按预期工作。 与服务器端相关的代码(使用Vertx Web GraphQL编写)如下所示,添加注释后,触发onNext将注释发送到发布者。 在客户端中,我混合使用HttpClient/WebClient,大多数时候,我想使用WebClient,它更容易处理表单帖子。但它似乎没有连接。 所以websocke