Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions DiscordRPC/DiscordRpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ public sealed class DiscordRpcClient : IDisposable
{
#region Properties

/// <summary>
/// Maximal amount of tries before aborting connection. If -1, then limit isn't present.
/// </summary>
/// <remarks>15 should be optimal value (~70s)</remarks>
public int MaxConnectionTries
{
get { return _maxConnectionTries; }
set
{
_maxConnectionTries = value;
if (connection != null) connection.MaxConnectionTries = value;
}
}
private int _maxConnectionTries;

/// <summary>
/// Gets a value indicating if the client has registered a URI Scheme. If this is false, Join events will fail.
Expand All @@ -41,7 +55,7 @@ public sealed class DiscordRpcClient : IDisposable
public int ProcessID { get; private set; }

/// <summary>
/// The maximum size of the message queue received from Discord.
/// The maximum size of the message queue received from Discord.
/// </summary>
public int MaxQueueSize { get; private set; }

Expand Down Expand Up @@ -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.
/// </summary>
public event OnRpcMessageEvent OnRpcMessage;

/// <summary>
/// Too many failed connection tries. You must reinitialize the client.
/// </summary>
public event OnTooManyConnectionTriesEvent OnTooManyConnectionTries;
#endregion

#region Initialization
Expand All @@ -215,7 +234,11 @@ public DiscordRpcClient(string applicationID) : this(applicationID, -1) { }
/// <param name="logger">The logger used to report messages. If null, then a <see cref="NullLogger"/> will be created and logs will be ignored.</param>
/// <param name="autoEvents">Should events be automatically invoked from the RPC Thread as they arrive from discord?</param>
/// <param name="client">The pipe client to use and communicate to discord through. If null, the default <see cref="ManagedNamedPipeClient"/> will be used.</param>
public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = null, bool autoEvents = true, INamedPipeClient client = null)
/// <param name="maxConnectionTries">
/// The maximum number of connection attempts before terminating.
/// Use -1 to disable the limit entirely. A value of 15 is typically optimal (~70 seconds).
/// </param>
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))
Expand All @@ -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();
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions DiscordRPC/Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ namespace DiscordRPC.Events
/// <param name="args">The arguments supplied with the event</param>
public delegate void OnConnectionFailedEvent(object sender, ConnectionFailedMessage args);

/// <summary>
/// Too many failed connection tries. You must reinitialize the client.
/// </summary>
/// <param name="sender">The Discord client handler that sent this event</param>
/// <param name="args">The arguments supplied with the event</param>
public delegate void OnTooManyConnectionTriesEvent(object sender, TooManyConnectionTriesMessage args);


/// <summary>
/// A RPC Message is received.
Expand Down
8 changes: 6 additions & 2 deletions DiscordRPC/Message/MessageType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum MessageType
/// The Discord Client has unsubscribed from an event.
/// </summary>
Unsubscribe,

/// <summary>
/// The Discord Client wishes for this process to join a game.
/// </summary>
Expand All @@ -59,6 +59,10 @@ public enum MessageType
/// <summary>
/// Failed to establish any connection with discord. Discord is potentially not running?
/// </summary>
ConnectionFailed
ConnectionFailed,
/// <summary>
/// Too many failed connection tries. You must reinitialize the client.
/// </summary>
TooManyConnectionTries
}
}
13 changes: 13 additions & 0 deletions DiscordRPC/Message/TooManyConnectionTriesMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace DiscordRPC.Message
{
/// <summary>
/// Too many failed connection tries. You must reinitialize the client.
/// </summary>
public class TooManyConnectionTriesMessage : IMessage
{
/// <summary>
/// The type of message received from discord
/// </summary>
public override MessageType Type { get { return MessageType.TooManyConnectionTries; } }
}
}
22 changes: 19 additions & 3 deletions DiscordRPC/RPC/RpcConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public ILogger Logger
}
private ILogger _logger;


public int MaxConnectionTries { get; set; }

/// <summary>
/// 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.
/// </summary>
Expand Down Expand Up @@ -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

/// <summary>
Expand All @@ -129,13 +133,15 @@ public RpcState State
/// <param name="client">The pipe client we shall use.</param>
/// <param name="maxRxQueueSize">The maximum size of the out queue</param>
/// <param name="maxRtQueueSize">The maximum size of the in queue</param>
public RpcConnection(string applicationID, int processID, int targetPipe, INamedPipeClient client, uint maxRxQueueSize = 128, uint maxRtQueueSize = 512)
/// <param name="maxConnectionTries">The maximum amount of tries taken before terminating</param>
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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
//{
Expand Down