0

I am using Vuetify together with Vuex and VueSocketIO for my WebApp and here is an example Part of the code:

Vue.use(new VueSocketIO({
      reconnection: true,
      debug: true,
      connection: SocketIO(`http://${process.env.ip}:4000`),
      vuex: {
        store,
        actionPrefix: 'SOCKET_',
      },
    }));

If I understand it correctly, using Vuex and VueSocketIO together makes it only possible to use one Socket like this at the same time.

In some cases Vue might not be able to connect to the socket specified at connection. I was wondering if there was a possibility to first let Vue try to connect to one socket (also with some number of reconnection attempts) but to switch to another connection value and try with that one afterwards as a fallback?

Thank you in advance!

Final solution

const options = {
  reconnection: true, 
  reconnectionAttempts: 2, 
  reconnectionDelay: 10,
  reconnectionDelayMax: 1,
  timeout: 300,
};

let connection = new SocketIO(`http://${process.env.ip}:4000`, options);
const instance = new VueSocketIO({
  debug: true,
  connection,
  vuex: {
    store,
    actionPrefix: 'SOCKET_',
  },
  options,
});

const options2 = {
  reconnection: true,
  reconnectionAttempts: 4,
};

connection.on('reconnect_failed', () => {
  connection = new SocketIO(`http://${process.env.fallback}:4000`, options2);
  instance.listener.io = connection;
  instance.listener.register();
  Vue.prototype.$socket = connection;
});
NotARobot
  • 455
  • 2
  • 10
  • 27

1 Answers1

1

To specify the number of reconnection attempts you can set reconnectionAttempts option.

Example Code:

const url = `http://${process.env.ip}:4000`
const options = {
  reconnectionAttempts: 3
}

Vue.use(new VueSocketIO({
  debug: true,
  connection: new SocketIO(url, options),
  vuex: { ... }
}))

But switching to another connection is not easy as both of vue-socket.io and socket.io-client it was not designed for that.

  • First we have to listen on reconnect_failed event which will fires when reconnection attempts is exceeded.

  • Then we have to create a new connection to connect to the fallback url.

  • The VueSocketIO instance have two important properties which emitter and listener we cannot create the new emitter since it might already used in some components (with subscribe function) so we have to use old emitter but new listener.

  • Unfortunately, we cannot import Listener class directly from vue-socket.io package. So we have to use old listener but change the io property to the new connection then manually call register method.

  • Binding Vue.prototype.$socket to the new connection for the future use.

Example Code:

const url = `http://${process.env.ip}:4000`
const fallbackUrl = `http://${process.env.ip}:4001`
const options = {
  reconnectionAttempts: 3
}

const connection = new SocketIO(url, options)
const instance = new VueSocketIO({
  debug: true,
  connection,
  vuex: {
    store,
    actionPrefix: 'SOCKET_'
  },
  options
})

connection.on('reconnect_failed', error => {
  const connection = new SocketIO(fallbackUrl, options)
  instance.listener.io = connection
  instance.listener.register()
  Vue.prototype.$socket = connection;
})

Vue.use(instance)
User 28
  • 4,863
  • 1
  • 20
  • 35
  • Thanks a lot for this detailed explanation! I would have never thought about this solution, especially with us not being able to change the emitter but only to change the io value. I made some first tests and this approach seems to work like a charme! – NotARobot Sep 30 '20 at 08:06
  • I realized it takes a lot of time until the switch of websocket connection happens if the first ip is not reachable. Is this probably related to this code or something different? – NotARobot Oct 13 '20 at 13:59
  • 1
    It will take about ~ `reconnectionAttempts` * `reconnectionDelay`. You can set `reconnectionDelayMax`. – User 28 Oct 13 '20 at 14:16
  • So I tried some rather extreme values (`reconnectionAttempts` to 1 and the `reconenctionDelayMax` to 1) but this did not change anything about how long I need to wait (about 30-40 sec). What am I doing wrong here? – NotARobot Oct 13 '20 at 14:23
  • 1
    I think `timeout` is also important here if your server is not responding. The default `timeout` is 20 seconds. – User 28 Oct 13 '20 at 15:45
  • Ah now I got it to work like intended! Thank you so much, you helped me a lot with my problem. (also I will add my final solution to my original question, for anybody who is interested) – NotARobot Oct 13 '20 at 18:20