diff --git a/DiscordRPC/DiscordRpcClient.cs b/DiscordRPC/DiscordRpcClient.cs
index 959aff23..49eb6d45 100644
--- a/DiscordRPC/DiscordRpcClient.cs
+++ b/DiscordRPC/DiscordRpcClient.cs
@@ -18,6 +18,20 @@ public sealed class DiscordRpcClient : IDisposable
{
#region Properties
+ ///
+ /// Maximal amount of tries before aborting connection. If -1, then limit isn't present.
+ ///
+ /// 15 should be optimal value (~70s)
+ public int MaxConnectionTries
+ {
+ get { return _maxConnectionTries; }
+ set
+ {
+ _maxConnectionTries = value;
+ if (connection != null) connection.MaxConnectionTries = value;
+ }
+ }
+ private int _maxConnectionTries;
///
/// Gets a value indicating if the client has registered a URI Scheme. If this is false, Join events will fail.
@@ -41,7 +55,7 @@ public sealed class DiscordRpcClient : IDisposable
public int ProcessID { get; private set; }
///
- /// The maximum size of the message queue received from Discord.
+ /// The maximum size of the message queue received from Discord.
///
public int MaxQueueSize { get; private set; }
@@ -197,6 +211,11 @@ public bool ShutdownOnly
/// The RPC Connection has sent a message. Called before any other event and executed from the RPC Thread.
///
public event OnRpcMessageEvent OnRpcMessage;
+
+ ///
+ /// Too many failed connection tries. You must reinitialize the client.
+ ///
+ public event OnTooManyConnectionTriesEvent OnTooManyConnectionTries;
#endregion
#region Initialization
@@ -215,7 +234,11 @@ public DiscordRpcClient(string applicationID) : this(applicationID, -1) { }
/// The logger used to report messages. If null, then a will be created and logs will be ignored.
/// Should events be automatically invoked from the RPC Thread as they arrive from discord?
/// The pipe client to use and communicate to discord through. If null, the default will be used.
- public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = null, bool autoEvents = true, INamedPipeClient client = null)
+ ///
+ /// The maximum number of connection attempts before terminating.
+ /// Use -1 to disable the limit entirely. A value of 15 is typically optimal (~70 seconds).
+ ///
+ public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = null, bool autoEvents = true, INamedPipeClient client = null, int maxConnectionTries = -1)
{
//Make sure appID is NOT null.
if (string.IsNullOrEmpty(applicationID))
@@ -228,6 +251,7 @@ public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = nu
HasRegisteredUriScheme = false;
AutoEvents = autoEvents;
SkipIdenticalPresence = true;
+ _maxConnectionTries = maxConnectionTries;
//Prepare the logger
_logger = logger ?? new NullLogger();
@@ -236,7 +260,8 @@ public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = nu
connection = new RpcConnection(ApplicationID, ProcessID, TargetPipe, client ?? new ManagedNamedPipeClient(), autoEvents ? 0 : 128U)
{
ShutdownOnly = _shutdownOnly,
- Logger = _logger
+ Logger = _logger,
+ MaxConnectionTries = _maxConnectionTries
};
//Subscribe to its event
@@ -405,6 +430,13 @@ private void ProcessMessage(IMessage message)
if (OnConnectionFailed != null)
OnConnectionFailed.Invoke(this, message as ConnectionFailedMessage);
break;
+
+ case MessageType.TooManyConnectionTries:
+ if (OnTooManyConnectionTries != null)
+ OnTooManyConnectionTries.Invoke(this, message as TooManyConnectionTriesMessage);
+
+ Deinitialize();
+ break;
//We got a message we dont know what to do with.
default:
diff --git a/DiscordRPC/Events.cs b/DiscordRPC/Events.cs
index 12df7cdf..2a75bb5a 100644
--- a/DiscordRPC/Events.cs
+++ b/DiscordRPC/Events.cs
@@ -85,6 +85,13 @@ namespace DiscordRPC.Events
/// The arguments supplied with the event
public delegate void OnConnectionFailedEvent(object sender, ConnectionFailedMessage args);
+ ///
+ /// Too many failed connection tries. You must reinitialize the client.
+ ///
+ /// The Discord client handler that sent this event
+ /// The arguments supplied with the event
+ public delegate void OnTooManyConnectionTriesEvent(object sender, TooManyConnectionTriesMessage args);
+
///
/// A RPC Message is received.
diff --git a/DiscordRPC/Message/MessageType.cs b/DiscordRPC/Message/MessageType.cs
index 223291ee..3e1f1f1e 100644
--- a/DiscordRPC/Message/MessageType.cs
+++ b/DiscordRPC/Message/MessageType.cs
@@ -35,7 +35,7 @@ public enum MessageType
/// The Discord Client has unsubscribed from an event.
///
Unsubscribe,
-
+
///
/// The Discord Client wishes for this process to join a game.
///
@@ -59,6 +59,10 @@ public enum MessageType
///
/// Failed to establish any connection with discord. Discord is potentially not running?
///
- ConnectionFailed
+ ConnectionFailed,
+ ///
+ /// Too many failed connection tries. You must reinitialize the client.
+ ///
+ TooManyConnectionTries
}
}
diff --git a/DiscordRPC/Message/TooManyConnectionTriesMessage.cs b/DiscordRPC/Message/TooManyConnectionTriesMessage.cs
new file mode 100644
index 00000000..32a76d7b
--- /dev/null
+++ b/DiscordRPC/Message/TooManyConnectionTriesMessage.cs
@@ -0,0 +1,13 @@
+namespace DiscordRPC.Message
+{
+ ///
+ /// Too many failed connection tries. You must reinitialize the client.
+ ///
+ public class TooManyConnectionTriesMessage : IMessage
+ {
+ ///
+ /// The type of message received from discord
+ ///
+ public override MessageType Type { get { return MessageType.TooManyConnectionTries; } }
+ }
+}
diff --git a/DiscordRPC/RPC/RpcConnection.cs b/DiscordRPC/RPC/RpcConnection.cs
index 52099049..51d28f7a 100644
--- a/DiscordRPC/RPC/RpcConnection.cs
+++ b/DiscordRPC/RPC/RpcConnection.cs
@@ -52,6 +52,9 @@ public ILogger Logger
}
private ILogger _logger;
+
+ public int MaxConnectionTries { get; set; }
+
///
/// Called when a message is received from the RPC and is about to be enqueued. This is cross-thread and will execute on the RPC thread.
///
@@ -118,6 +121,7 @@ public RpcState State
private AutoResetEvent queueUpdatedEvent = new AutoResetEvent(false);
private BackoffDelay delay; //The backoff delay before reconnecting.
+ private int tries; //number of unsuccessful connections in row
#endregion
///
@@ -129,13 +133,15 @@ public RpcState State
/// The pipe client we shall use.
/// The maximum size of the out queue
/// The maximum size of the in queue
- public RpcConnection(string applicationID, int processID, int targetPipe, INamedPipeClient client, uint maxRxQueueSize = 128, uint maxRtQueueSize = 512)
+ /// The maximum amount of tries taken before terminating
+ public RpcConnection(string applicationID, int processID, int targetPipe, INamedPipeClient client, uint maxRxQueueSize = 128, uint maxRtQueueSize = 512, int maxConnectionTries = -1)
{
this.applicationID = applicationID;
this.processID = processID;
this.targetPipe = targetPipe;
- this.namedPipe = client;
- this.ShutdownOnly = true;
+ namedPipe = client;
+ ShutdownOnly = true;
+ MaxConnectionTries = maxConnectionTries;
//Assign a default logger
Logger = new ConsoleLogger();
@@ -316,6 +322,7 @@ private void MainLoop()
//Attempt to establish a handshake
EstablishHandshake();
Logger.Trace("Connection Established. Starting reading loop...");
+ tries = 0;
//Continously iterate, waiting for the frame
//We want to only stop reading if the inside tells us (mainloop), if we are aborting (abort) or the pipe disconnects
@@ -431,9 +438,18 @@ private void MainLoop()
// so we are going to wait a bit before doing it again
long sleep = delay.NextDelay();
+ tries++;
+
Logger.Trace("Waiting {0}ms before attempting to connect again", sleep);
Thread.Sleep(delay.NextDelay());
}
+ if (tries >= MaxConnectionTries && MaxConnectionTries != -1)
+ {
+ Logger.Error("Terminating attempts to connect, exceeded amount of tries");
+
+ EnqueueMessage(new TooManyConnectionTriesMessage());
+ break;
+ }
}
//catch(InvalidPipeException e)
//{