A lot can get in the way of network connectivity – be it human error, device failure, or environmental events – especially on mobile. A reliable connection is crucial for the successful transmission of video, audio, and data in a WebRTC application. So, when connectivity is compromised, you need to sniff out trouble quickly and reestablish the connection seamlessly.

In this post, we will take a look at how to implement a reconnection mechanism for a mobile WebRTC application. We’ll call the mechanism, “Watchdog”.

While the premise is the same for iOS, the code below is for Android applications. 

Understanding The Reconnection Mechanism

Our “Watchdog” reconnection mechanism works by keeping an eye on two important elements from the WebRTC flow: Signaling and the IceConnectionStateChange event going into a disconnected or failed state.

Signaling involves exchanging information to establish a connection and, once the connection is established, it allows additional messages to be exchanged. This is useful during compromising situations, such as network event changes where it is required to perform a new negotiation in order to keep the peer connection up. For example, the user has moved to a mobile network or the current connection has been terminated by a restrictive firewall.

In that regard, it is crucial to keep this communication open even after the peer connection has been established. Equally important is detecting interruptions, such as terminated WebSocket connections or unresponsive REST endpoints (assuming these are the methods used for signaling), as they may indicate network issues, and therefore, a signaling reset or a full WebRTC reconnection it’s necessary.

The IceConnectionChangeEvent is a PeerConnection event that takes place during the connection negotiation process, more specifically, it is triggered each time the ICE connection state changes. A healthy connection would start at a new state, transition through checking, then connected, and finally completed

However, additional states can appear under certain conditions. Failed and disconnected are two that require special attention from the application code, as these states suggest possible connection problems. 

For any of these events, the goal is to have proper listeners that update the user interface accordingly. They must also register a Network Change Broadcast Receiver so the application is aware when connectivity is recovered and then attempts to reconnect automatically. 

This process is depicted in the image below.

Depiction of the reconnection mechanism.

Implementing The Reconnection Mechanism 

As mentioned above, the code below is for Android applications only. 

The first thing to do is to create the task that performs reconnection after connectivity is recovered. The TimerTask class is a great way to do this. A template of such a task is shown below.

private var connectivityTask: TimerTask? = object : TimerTask() {
   override fun run() {
     //logic to re establish the Signaling Socket and initialize the PeerConnection
   }
}

The next step is to create proper event listeners in the code. This will let the application know when the network is not available. For instance, the code below shows an example of listening for IceConnectionStateChange events and registering a Broadcast Receiver that receives messages of changes in the network from the Android system. This way the application will be notified when connectivity is recovered.

override fun onIceConnectionChange
  (
    iceConnectionState: PeerConnection.IceConnectionState
  ) {
   super.onIceConnectionChange(iceConnectionState)

   // Check the state of the ICE connection
   if (iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED) {

     // use a counter to limit the attempts
     if(attempt<10){ 
       
       // initialize Connectivity Check Broadcast Receiver
       val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
       registerReceiver(connectivityReceiver, intentFilter)
       
       // increase attempts counter
       attempt++
     } else {
       // A permanent error: move user to login screen and display error message, etc
     }
  }
}

In the Broadcast Receiver, the code below shows how to check if a connection is available and if so, schedules the connectivity task that re-establish the WebRTC connection. If that’s not the case, the UI needs to be updated to reflect the current status of the network.

class ConnectivityReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // get the information from the network state
        val connManager = context.getSystemService(
          Context.CONNECTIVITY_SERVICE
          ) as ConnectivityManager
        val networkCapabilities = connManager.activeNetwork ?: return
        val capabilities = connManager.getNetworkCapabilities(networkCapabilities)
        
        // check if network is available
        val isConnected = capabilities != null &&
              (
                 capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                 capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
              )
        if (isConnected) {
           // schedule Connectivity Task Here, after Android M
           val connectivityWatchDog = Timer()
           connectivityWatchDog.schedule(connectivityTask,0)
        } else {
            // internet is not available
        }
   }
}

Once The session is connected again make sure to reset the attempts counter:

attempt=0

Conclusion

The ability to handle connectivity loss events properly and also self heal once the connection is restored is invaluable for any WebRTC application. By following the approach outlined in this post, developers can easily add this feature to their application, providing a robust user experience even in the event of a network failure, while also adding resilience to it.

If you’re looking to implement such a Watchdog into your application or need assistance with high-quality and reliable WebRTC applications for Android and iOS devices, don’t hesitate to contact us at WebRTC.ventures. Let’s make it live!

Recent Blog Posts