使用带有 React 和 Apollo 的 graphql 订阅制作实时应用程序

Posted

技术标签:

【中文标题】使用带有 React 和 Apollo 的 graphql 订阅制作实时应用程序【英文标题】:Making a real time application using graphql subscriptions with React and Apollo 【发布时间】:2017-11-30 01:03:26 【问题描述】:

我正在使用 React、Apollo 和 GraphQL 构建一个实时应用程序。我的计划是组件将发出查询,然后依赖订阅来保持客户端缓存与后端数据实时一致。但是,我不相信这会起作用,因为在卸载组件时我将不得不取消订阅。当组件再次挂载时,结果将从查询缓存中获取,因此它们实际上会过期,因为在订阅关闭后发生的所有更改都将丢失。再次打开订阅也意味着结果会变得一团糟,因为在这期间错过了更改。

例如,在组件 A 中,如果我有一个查询:-

query 
  customers 
    id
    name
    phoneNo
  

和订阅:-

subscription customersUpdated 
  customersUpdated 
    id
    name
    phoneNo
  

customers 查询在 A 首次挂载时运行。结果被缓存。在订阅customersUpdated 的帮助下记录对客户数据的所有更改。请注意,订阅不会返回所有客户,而只会返回需要合并到查询缓存中的更改。卸载 A 时,我取消订阅。假设另一个用户对客户数据进行了 5 次更改,而 A 为我们当前的用户保持卸载状态。当 A 再次挂载时,这 5 个更改已丢失,查询只是从缓存中获取结果。订阅重新开始,但现在数据处于错误状态,因为我们错过了这 5 项更改并且永远不会得到它们!

在此处使用订阅的正确模式是什么?我试图避免使用查询进行基于时间的重新获取,因为我希望应用程序实时工作。同样是实时的,我只想拉取更改,而不是不必要地拉取所有数据。

【问题讨论】:

你可以试试 apollo-link-firebase github.com/Canner/apollo-link-firebase。支持使用 apollo-link 和 firebase 客户端 js sdk 进行实时订阅。 【参考方案1】:

你可以做一些事情:

    只需在您的 GraphQL 查询中使用 network-onlycache-and-network 获取策略,以便您在安装组件时获得最新数据。像往常一样初始化订阅。 在组件卸载时不要停止订阅,并在组件之外处理您的订阅生命周期。这可能需要更多的工作,但您可以控制它何时开始和停止。

但是,我建议您更多地考虑应用程序的哪些部分实际上需要实时。在大多数应用程序中,只有一小部分体验需要低延迟数据更新,因此仅在小情况下使用订阅可能是更好的策略。归根结底,通常更容易推断无状态架构的可扩展性。

【讨论】:

我想做一些像firebase这样的东西,其中一切都是实时的,所有数据都通过套接字发送。我必须弄清楚我现在应该采取什么方法。感谢您的选择!订阅的另一个问题是,看起来每个订阅都打开了与服务器的新连接,这意味着服务器可能不得不处理太多的负载。难道这一切都不能通过一个套接字连接完成吗? 所有订阅都在一个连接上运行,是否有什么东西让每个订阅看起来都有一个新连接?是的,如果你想要像 Firebase 这样工作的东西,那么 Firebase 是最好的选择——GraphQL 没有相同的功能集。如果您想要一个一切都是实时的开源解决方案,您也可以尝试 Meteor。 如何使用 gun js 和 graphql 来构建实时离线第一个应用程序?我将再次检查连接问题。我收到一个错误,似乎表明有多个连接。

以上是关于使用带有 React 和 Apollo 的 graphql 订阅制作实时应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在本地网络上部署带有 apollo 客户端和 apollo-server 后端的 React 应用程序

使用带有反应生命周期方法的 react-apollo 2.1 突变

使用带有 react-apollo 查询的变量

如何使用带有 react-apollo 的模拟数据进行测试

React - 带有输入变量的 Apollo 客户端查询

带有 React 的 Apollo 客户端 2 无法进行查询