Reregister and Reconnect
To protect users from connection failures, it's recommended that you add re-connect logic to your app to ensure network failures have minimal impact on end-users.
There are two places this must be performed:
- Gateway Registration
- Media Server Connection
Reregister on Gateway Connection Failures
// Track whether the user has decided to leave (unregister)
// If they have not and the client gets into the Disconnected state then we attempt to reregister (reconnect) automatically.
private bool _Unregistering = false;
private int _ReregisterBackoff = 200;
private int _MaxRegisterBackoff = 60000;
public void Join()
{
_Unregistering = false;
_Client = new Client(GatewayUrl, _ApplicationId);
var ChannelClaims = new[] { new ChannelClaim(ChannelId) };
_Client.Tag = Mode.ToString();
_Client.DeviceAlias = "a-device-alias";
_Client.UserAlias = Name;
string Token = GenerateToken(ChannelClaims);
_Client.OnStateChange += (client) =>
{
if (client.State == ClientState.Registering)
{
Log.Debug("client is registering");
}
else if (client.State == ClientState.Registered)
{
Log.Debug("client is registered");
}
else if (client.State == ClientState.Unregistering)
{
Log.Debug("client is unregistering");
}
else if (client.State == ClientState.Unregistered)
{
Log.Debug("client is unregistered");
// Client has failed as it is unregistering due to external factors.
if (!_Unregistering)
{
// Back off our reregister attempts as they continue to fail to avoid runaway process.
ManagedThread.Sleep(_ReregisterBackoff);
if (_ReregisterBackoff < _MaxRegisterBackoff)
{
_ReregisterBackoff += _ReregisterBackoff;
}
// ReRegister
Token = GenerateToken(ChannelClaims); // ensure token has not expired
_Client.Register(Token)
.Then<object>(channels =>
{
_ReregisterBackoff = 200; // reset for next time
return OnClientRegistered(channels);
})
.Fail((e) =>
{
Log.Error("Failed to register with Gateway.", e);
});
}
}
};
return _Client.Register(Token)
.Then<object>(channels =>
{
return OnClientRegistered(channels);
})
.Fail((e) =>
{
Log.Error("Failed to register with Gateway.", e);
});
}
public void Leave()
{
// Set _Unregistering to true prior to calling _Client.Unregister();
_Unregistering = true;
return _Client.Unregister();
}
Reconnect on Connection Failure
// Subscribe to connection state change events and listen for connection failures
connection.OnStateChange += (conn) =>
{
if (conn.State == ConnectionState.Failed)
{
// Create a new connection here e.g.
McuConnection connection;
DataChannel dataChannel = PrepareDataChannel();
DataStream dataStream = new DataStream(dataChannel);
lock (_DataChannelLock)
{
_DataChannels.Add(dataChannel);
}
var audioStream = new AudioStream(_LocalMedia, remoteMedia);
var videoStream = new VideoStream(_LocalMedia, remoteMedia);
// (Using _channelObject obtained from Client.Register() call)
connection = _channelObject.CreateMcuConnection(audioStream, videoStream, dataStream);
}
}