Automatically reconnect to the server using an exponential backoff algorithm if we lose our connection.

This commit is contained in:
Starbeamrainbowlabs 2018-12-02 16:31:54 +00:00
parent 002ec0f7d9
commit 19be6f8425
Signed by: sbrl
GPG key ID: 1BE5172E637709C2

View file

@ -29,7 +29,21 @@ namespace RhinoReminds
public string ReminderFilePath { get; set; } = "./reminders.xml"; public string ReminderFilePath { get; set; } = "./reminders.xml";
private ReminderList reminderList = new ReminderList(); private ReminderList reminderList = new ReminderList();
private XmppClient client; private XmppClient client;
/// <summary>
/// The number of seconds to wait before trying to reconnect to the
/// server again if we loose our connection again.
/// </summary>
private int nextBackoffDelay = 1;
private int defaultBackoffDelay = 1;
private float backoffDelayMultiplier = 2;
/// <summary>
/// If a connection attempt doesn't succeed in this number of seconds,
/// give up and try again later.
/// </summary>
private int giveUpTimeout = 30;
public ClientListener(string inJid, string inPassword) public ClientListener(string inJid, string inPassword)
{ {
@ -51,19 +65,36 @@ namespace RhinoReminds
client.SubscriptionRequest += subscriptionRequestHandler; client.SubscriptionRequest += subscriptionRequestHandler;
// Connect to the server. This starts it's own thread that doesn't block the program exiting, apparently // Connect to the server. This starts it's own thread that doesn't block the program exiting, apparently
client.Connect(); await connect();
while (!client.Connected)
await Task.Delay(100);
Console.WriteLine($"[Rhino/Setup] Connected as {Jid}");
//client.SetStatus(Availability.Online); //client.SetStatus(Availability.Online);
await watchForReminders(); await watchForReminders();
} }
private async Task<bool> connect()
{
if (client.Connected)
return true;
DateTime startTime = DateTime.Now;
client.Connect();
while (!client.Connected)
{
if ((DateTime.Now - startTime).TotalSeconds > giveUpTimeout)
return false;
await Task.Delay(100);
}
Console.WriteLine($"[Rhino/Setup] Connected as {Jid}");
return true;
}
#region XMPP Event Handling #region XMPP Event Handling
private bool subscriptionRequestHandler(Jid from) private bool subscriptionRequestHandler(Jid from)
{ {
if (!AllowedDomains.Contains("*") && !AllowedDomains.Contains(from.Domain)) { if (!AllowedDomains.Contains("*") && !AllowedDomains.Contains(from.Domain)) {
@ -77,6 +108,13 @@ namespace RhinoReminds
private void errorHandler(object sender, S22.Xmpp.Im.ErrorEventArgs e) private void errorHandler(object sender, S22.Xmpp.Im.ErrorEventArgs e)
{ {
Console.Error.WriteLine($"Error {e.Reason}: {e.Exception}"); Console.Error.WriteLine($"Error {e.Reason}: {e.Exception}");
Console.Error.WriteLine($"Reconnecting in {TimeSpan.FromSeconds(nextBackoffDelay).ToString()}.");
Task.Delay(nextBackoffDelay * 1000).Wait();
if (!connect().Result)
nextBackoffDelay = (int)Math.Ceiling(nextBackoffDelay * backoffDelayMultiplier);
else
nextBackoffDelay = defaultBackoffDelay;
} }
private void messageHandlerRoot(object sender, MessageEventArgs eventArgs) private void messageHandlerRoot(object sender, MessageEventArgs eventArgs)
@ -96,6 +134,9 @@ namespace RhinoReminds
} }
} }
#endregion
public void SetAvatar(string avatarFilepath) public void SetAvatar(string avatarFilepath)
{ {
if (!client.Connected) if (!client.Connected)
@ -219,6 +260,7 @@ namespace RhinoReminds
} }
} }
#region Outgoing #region Outgoing
/// <summary> /// <summary>
/// Sends a chat message to the specified JID. /// Sends a chat message to the specified JID.