Peerjs: How can peer.js reconnect to the same peer after disconnection?

Created on 14 Apr 2020  ·  7Comments  ·  Source: peers/peerjs

i need to know if 2 peers are connected on call when we get message - ice connection state is disconnected, it close all windows and dicsonnect 2 peer. Can we handle to reconnect when ice server disconnect?

bug

Most helpful comment

I want to know how i can reconnect when iceconnection disconnect? I have tried so many code but it doesnt work

This library will not allow you to do a graceful recovery of the disconnected state because it immediately closes the connection. The only thing you can do is listen to on('error') and then connect the exact same way you did when you setup your original connection. It's quite a pain.

note: there are two places to check for errors. On peer itself and on the connection itself. On the connection, they're pretty much all fatal the way this library is now, although they shouldn't be. On the peer itself, many of errors are fatal, but not all.

For socket errors on peer I have something like this:

this.peer.on('disconnected', () => {
        this.disconnectBackoff = 1;
        this.retrySocketConnection();
      });

where backoff is a value in seconds which I increment everytime I try up to a maximum.

For the peer error I have something like this:

// Non-Fatal error:
// 'peer-unavailable' = maybe they left?
// 'disconnected' = this means the Peering server disconnected, we have a seperate retry for that on('disconnect')
// pretty much all of the rest are fatal.
const FATAL_ERRORS = ['invalid-id', 'invalid-key', 'network', 'ssl-unavailable', 'server-error', 'socket-error', 'socket-closed', 'unavailable-id', 'webrtc'];
this.peer.on('error', (e) => {
        if (FATAL_ERRORS.includes(e.type)) {
          this.reconnectTimeout(e); // this function waits then tries the entire connection over again
        } else {
          console.log('Non fatal error: ',  e.type);
        }
      });

And then for the connection (mediaConnection in my case) I have this.

call.on('error', (e) => {
      console.warn('error with stream', e);
      if (initiator) { // initiator is a value I set myself
        // Optionally this should call only the user that failed instead of the whole thing
        this.reconnectTimeout();
      }
    });

And the aformentioned reconnectTimeout is a simple function that tries the entire connection over again.

In theory this library could handle iceRestarts and not be fatal on ice disconnect, which I believe would resolve the majority of issues. I have a PR for the disconnect thing, but not yet for the restarts.

All 7 comments

ice state disconnected should be recoverable, but currently this library closes the connection pre-maturely. Until that's handled, the best you can do is put a timer on error and reconnect.

I want to know how i can reconnect when iceconnection disconnect? I have tried so many code but it doesnt work

I want to know how i can reconnect when iceconnection disconnect? I have tried so many code but it doesnt work

This library will not allow you to do a graceful recovery of the disconnected state because it immediately closes the connection. The only thing you can do is listen to on('error') and then connect the exact same way you did when you setup your original connection. It's quite a pain.

note: there are two places to check for errors. On peer itself and on the connection itself. On the connection, they're pretty much all fatal the way this library is now, although they shouldn't be. On the peer itself, many of errors are fatal, but not all.

For socket errors on peer I have something like this:

this.peer.on('disconnected', () => {
        this.disconnectBackoff = 1;
        this.retrySocketConnection();
      });

where backoff is a value in seconds which I increment everytime I try up to a maximum.

For the peer error I have something like this:

// Non-Fatal error:
// 'peer-unavailable' = maybe they left?
// 'disconnected' = this means the Peering server disconnected, we have a seperate retry for that on('disconnect')
// pretty much all of the rest are fatal.
const FATAL_ERRORS = ['invalid-id', 'invalid-key', 'network', 'ssl-unavailable', 'server-error', 'socket-error', 'socket-closed', 'unavailable-id', 'webrtc'];
this.peer.on('error', (e) => {
        if (FATAL_ERRORS.includes(e.type)) {
          this.reconnectTimeout(e); // this function waits then tries the entire connection over again
        } else {
          console.log('Non fatal error: ',  e.type);
        }
      });

And then for the connection (mediaConnection in my case) I have this.

call.on('error', (e) => {
      console.warn('error with stream', e);
      if (initiator) { // initiator is a value I set myself
        // Optionally this should call only the user that failed instead of the whole thing
        this.reconnectTimeout();
      }
    });

And the aformentioned reconnectTimeout is a simple function that tries the entire connection over again.

In theory this library could handle iceRestarts and not be fatal on ice disconnect, which I believe would resolve the majority of issues. I have a PR for the disconnect thing, but not yet for the restarts.

sir i am using peer.js for whole project here is the link for peerjs file
https://github.com/peers/peerjs/blob/master/dist/peerjs.js

now what i am getting problem when 2 peers connected each other for video call, when one peer get slow connection iceconnection disconnect both peer

and this is the code in peerjs file where it is disconnecting both peer

```
peerConnection.oniceconnectionstatechange = function () {
switch (peerConnection.iceConnectionState) {
case "failed":
logger_1.default.log("iceConnectionState is failed, closing connections to " + peerId);

      _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Negotiation of connection to " + peerId + " failed."));

      _this.connection.close();

      break;

    case "closed":
      logger_1.default.log("iceConnectionState is closed, closing connections to " + peerId);

      _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Connection to " + peerId + " closed."));

      _this.connection.close();

      break;

    case "disconnected":
      logger_1.default.log("iceConnectionState is disconnected, closing connections to " + peerId);

      _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Connection to " + peerId + " disconnected."));

      _this.connection.close();

      break;

    case "completed":
      peerConnection.onicecandidate = util_1.util.noop;
      break;
  }

  _this.connection.emit(enums_1.ConnectionEventType.IceStateChanged, peerConnection.iceConnectionState);
}; // DATACONNECTION.

please check this code 

case "disconnected":
logger_1.default.log("iceConnectionState is disconnected, closing connections to " + peerId);

      _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Connection to " + peerId + " disconnected."));

      **_this.connection.close();**

```

here connection get close and here i want to reconnect ice connection

Reread my reply. I explained it as clearly as I know how.

This library will not allow you to do a graceful recovery of the disconnected state because it immediately closes the connection. The only thing you can do is listen to on('error') and then connect the exact same way you did when you setup your original connection. It's quite a pain.

Your only other option is to fork it, or use my fork here: https://github.com/peers/peerjs/pull/655

any other option? or if you can help me in peer js where and what code i should write on error?
i am really stuck sir....

@jrowny thanks for an investigation. we'll ship it in 1.3.0

Was this page helpful?
0 / 5 - 0 ratings