简体   繁体   English

Apollo 订阅 - 使用 subscribeToMore 处理 WS 断开连接

[英]Apollo subscriptions - handling WS disconnects with subscribeToMore

I've been looking for a way to handle web socket disconnects in my React app with Apollo subscriptions and have not found a way to do so.我一直在寻找一种方法来处理我的 React 应用程序中使用 Apollo 订阅的网络套接字断开连接,但还没有找到这样做的方法。 The other examples I see in the apollo documentation show the below method for catching a reconnect:我在 apollo 文档中看到的其他示例显示了以下用于捕获重新连接的方法:

  const wsClient = process.browser ? new SubscriptionClient(WSendpoint, {
    reconnect: true,
  }) : null;

  const wsLink = process.browser ? new WebSocketLink(wsClient) : null;

  if (process.browser) {
    wsLink.subscriptionClient.on(
      'reconnected',
      () => {
        console.log('reconnected')
      },
    )
  }

There are two issues with the above method:上述方法有两个问题:

  1. is that is does not catch when the user disconnects from their internet (only from when the server restarts for whatever reason)当用户断开互联网连接时(仅当服务器因任何原因重新启动时)时,这不会被捕获
  2. that the reconnect is triggered outside of my React apps components.重新连接是在我的 React 应用程序组件之外触发的。

What I would like to be able to do is to is reload my "chat" component if the user either disconnects from their internet or if my express server goes down for any reason.我希望能够做的是,如果用户与互联网断开连接或者我的快速服务器因任何原因出现故障,则重新加载我的“聊天”组件。 For this to happen I would need my chat component to completely reload which i'm not sure would be possible from outside my component tree.为此,我需要我的聊天组件完全重新加载,我不确定这是否可以从我的组件树外部进行。

Is there a method in the Query or Subscription Apollo components to be able to capture this event and handle it accordingly from the component? QuerySubscription Apollo 组件中是否有方法能够捕获此事件并从组件中相应地处理它?

There are a few ways I can think of to handle these cases but none of them are a one-shot solution, each case needs to be handled independently.我可以想到几种方法来处理这些情况,但它们都不是一次性解决方案,每种情况都需要独立处理。

  1. Setup a online/offline listener ( ref )设置online/offline侦听器 ( ref )
  2. Setup an Apollo middleware to handle network errors from your server ( ref )设置Apollo middleware来处理来自服务器的网络错误( 参考
  3. Create a variable in your store, isOnline for example, which can hold a global reference of your app's state.在您的商店中创建一个变量,例如isOnline ,它可以保存应用程序状态的全局引用。 Whenever the above two methods trigger, you could update the value of isOnline每当上述两种方法触发时,您都可以更新isOnline的值
  4. Finally, to bundle all of it together.最后,将所有这些捆绑在一起。 Create a react HOC which uses isOnline to handle the network state for each component.创建一个React HOC ,它使用isOnline来处理每个组件的网络状态。 This can be used to handle network error messages, refresh components once network is restored.这可用于处理网络错误消息,一旦网络恢复就刷新组件。

You can use SubscriptionClient callbacks from subscriptions-transport-ws , like this:您可以使用来自subscriptions-transport-ws SubscriptionClient回调,如下所示:

const ws = require("ws");
const { SubscriptionClient } = require("subscriptions-transport-ws");
const { WebSocketLink } = require("apollo-link-ws");
const { ApolloClient } = require("apollo-client");
const { InMemoryCache } = require("apollo-cache-inmemory");

const subClient = new SubscriptionClient(
    'ws://localhost:4000/graphql',
    { reconnect: true },
    ws
);

subClient.onConnected(() => { console.log("onConnected") });
subClient.onReconnected(() => { console.log("onReconnected") });
subClient.onReconnecting(() => { console.log("onReconnecting") });
subClient.onDisconnected(() => { console.log("onDisconnected") });
subClient.onError(error => { console.log("onError", error.message) });

const wsLink = new WebSocketLink(subClient);

const client = new ApolloClient({
    link: wsLink,
    cache: new InMemoryCache()
});

I'm using this for Node.js, but it will probably work for React too.我将它用于 Node.js,但它可能也适用于 React。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM