最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Apollo subscriptions - handling WS disconnects with subscribeToMore - Stack Overflow

programmeradmin4浏览0评论

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. The other examples I see in the apollo documentation show the below method for catching a reconnect:

  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 ponents.

What I would like to be able to do is to is reload my "chat" ponent 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 ponent to pletely reload which i'm not sure would be possible from outside my ponent tree.

Is there a method in the Query or Subscription Apollo ponents to be able to capture this event and handle it accordingly from the ponent?

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. The other examples I see in the apollo documentation show the below method for catching a reconnect:

  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 ponents.

What I would like to be able to do is to is reload my "chat" ponent 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 ponent to pletely reload which i'm not sure would be possible from outside my ponent tree.

Is there a method in the Query or Subscription Apollo ponents to be able to capture this event and handle it accordingly from the ponent?

Share Improve this question edited Feb 26, 2019 at 20:39 red house 87 asked Feb 19, 2019 at 9:41 red house 87red house 87 2,42512 gold badges61 silver badges110 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 1

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)
  2. Setup an Apollo middleware to handle network errors from your server (ref)
  3. Create a variable in your store, isOnline for example, which can hold a global reference of your app's state. Whenever the above two methods trigger, you could update the value of isOnline
  4. Finally, to bundle all of it together. Create a react HOC which uses isOnline to handle the network state for each ponent. This can be used to handle network error messages, refresh ponents once network is restored.

You can use SubscriptionClient callbacks from subscriptions-transport-ws, like this:

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.

发布评论

评论列表(0)

  1. 暂无评论