Browse Source

Merge 5fdfee89ce into 479361bbea

pull/806/merge
Radka Janeková GitHub 8 years ago
parent
commit
a2f9734b00
5 changed files with 61 additions and 43 deletions
  1. +6
    -0
      src/Discord.Net.Rpc/DiscordRpcClient.Events.cs
  2. +8
    -7
      src/Discord.Net.Rpc/DiscordRpcClient.cs
  3. +19
    -15
      src/Discord.Net.WebSocket/ConnectionManager.cs
  4. +6
    -0
      src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs
  5. +22
    -21
      src/Discord.Net.WebSocket/DiscordSocketClient.cs

+ 6
- 0
src/Discord.Net.Rpc/DiscordRpcClient.Events.cs View File

@@ -6,6 +6,12 @@ namespace Discord.Rpc
public partial class DiscordRpcClient public partial class DiscordRpcClient
{ {
//General //General
public event Func<Task> Connecting
{
add { _connectingEvent.Add(value); }
remove { _connectingEvent.Remove(value); }
}
private readonly AsyncEvent<Func<Task>> _connectingEvent = new AsyncEvent<Func<Task>>();
public event Func<Task> Connected public event Func<Task> Connected
{ {
add { _connectedEvent.Add(value); } add { _connectedEvent.Add(value); }


+ 8
- 7
src/Discord.Net.Rpc/DiscordRpcClient.cs View File

@@ -29,7 +29,7 @@ namespace Discord.Rpc
public RestApplication ApplicationInfo { get; private set; } public RestApplication ApplicationInfo { get; private set; }


/// <summary> Creates a new RPC discord client. </summary> /// <summary> Creates a new RPC discord client. </summary>
public DiscordRpcClient(string clientId, string origin)
public DiscordRpcClient(string clientId, string origin)
: this(clientId, origin, new DiscordRpcConfig()) { } : this(clientId, origin, new DiscordRpcConfig()) { }
/// <summary> Creates a new RPC discord client. </summary> /// <summary> Creates a new RPC discord client. </summary>
public DiscordRpcClient(string clientId, string origin, DiscordRpcConfig config) public DiscordRpcClient(string clientId, string origin, DiscordRpcConfig config)
@@ -38,8 +38,9 @@ namespace Discord.Rpc
_stateLock = new SemaphoreSlim(1, 1); _stateLock = new SemaphoreSlim(1, 1);
_authorizeLock = new SemaphoreSlim(1, 1); _authorizeLock = new SemaphoreSlim(1, 1);
_rpcLogger = LogManager.CreateLogger("RPC"); _rpcLogger = LogManager.CreateLogger("RPC");
_connection = new ConnectionManager(_stateLock, _rpcLogger, config.ConnectionTimeout,
OnConnectingAsync, OnDisconnectingAsync, x => ApiClient.Disconnected += x);
_connection = new ConnectionManager(_stateLock, _rpcLogger, config.ConnectionTimeout,
ConnectAsync, DisconnectAsync, x => ApiClient.Disconnected += x);
_connection.Connecting += () => _connectingEvent.InvokeAsync();
_connection.Connected += () => _connectedEvent.InvokeAsync(); _connection.Connected += () => _connectedEvent.InvokeAsync();
_connection.Disconnected += (ex, recon) => _disconnectedEvent.InvokeAsync(ex); _connection.Disconnected += (ex, recon) => _disconnectedEvent.InvokeAsync(ex);


@@ -49,7 +50,7 @@ namespace Discord.Rpc
_rpcLogger.WarningAsync(e.ErrorContext.Error).GetAwaiter().GetResult(); _rpcLogger.WarningAsync(e.ErrorContext.Error).GetAwaiter().GetResult();
e.ErrorContext.Handled = true; e.ErrorContext.Handled = true;
}; };
ApiClient.SentRpcMessage += async opCode => await _rpcLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); ApiClient.SentRpcMessage += async opCode => await _rpcLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false);
ApiClient.ReceivedRpcEvent += ProcessMessageAsync; ApiClient.ReceivedRpcEvent += ProcessMessageAsync;
} }
@@ -68,14 +69,14 @@ namespace Discord.Rpc
public Task StartAsync() => _connection.StartAsync(); public Task StartAsync() => _connection.StartAsync();
public Task StopAsync() => _connection.StopAsync(); public Task StopAsync() => _connection.StopAsync();


private async Task OnConnectingAsync()
private async Task ConnectAsync()
{ {
await _rpcLogger.DebugAsync("Connecting ApiClient").ConfigureAwait(false); await _rpcLogger.DebugAsync("Connecting ApiClient").ConfigureAwait(false);
await ApiClient.ConnectAsync().ConfigureAwait(false); await ApiClient.ConnectAsync().ConfigureAwait(false);


await _connection.WaitAsync().ConfigureAwait(false); await _connection.WaitAsync().ConfigureAwait(false);
} }
private async Task OnDisconnectingAsync(Exception ex)
private async Task DisconnectAsync(Exception ex)
{ {
await _rpcLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false); await _rpcLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false);
await ApiClient.DisconnectAsync().ConfigureAwait(false); await ApiClient.DisconnectAsync().ConfigureAwait(false);
@@ -313,7 +314,7 @@ namespace Discord.Rpc
ApplicationInfo = RestApplication.Create(this, response.Application); ApplicationInfo = RestApplication.Create(this, response.Application);
Scopes = response.Scopes; Scopes = response.Scopes;
TokenExpiresAt = response.Expires; TokenExpiresAt = response.Expires;
var __ = _connection.CompleteAsync(); var __ = _connection.CompleteAsync();
await _rpcLogger.InfoAsync("Ready").ConfigureAwait(false); await _rpcLogger.InfoAsync("Ready").ConfigureAwait(false);
} }


+ 19
- 15
src/Discord.Net.WebSocket/ConnectionManager.cs View File

@@ -8,6 +8,8 @@ namespace Discord
{ {
internal class ConnectionManager internal class ConnectionManager
{ {
public event Func<Task> Connecting { add { _connectingEvent.Add(value); } remove { _connectingEvent.Remove(value); } }
private readonly AsyncEvent<Func<Task>> _connectingEvent = new AsyncEvent<Func<Task>>();
public event Func<Task> Connected { add { _connectedEvent.Add(value); } remove { _connectedEvent.Remove(value); } } public event Func<Task> Connected { add { _connectedEvent.Add(value); } remove { _connectedEvent.Remove(value); } }
private readonly AsyncEvent<Func<Task>> _connectedEvent = new AsyncEvent<Func<Task>>(); private readonly AsyncEvent<Func<Task>> _connectedEvent = new AsyncEvent<Func<Task>>();
public event Func<Exception, bool, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } } public event Func<Exception, bool, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
@@ -16,8 +18,8 @@ namespace Discord
private readonly SemaphoreSlim _stateLock; private readonly SemaphoreSlim _stateLock;
private readonly Logger _logger; private readonly Logger _logger;
private readonly int _connectionTimeout; private readonly int _connectionTimeout;
private readonly Func<Task> _onConnecting;
private readonly Func<Exception, Task> _onDisconnecting;
private readonly Func<Task> _connect;
private readonly Func<Exception, Task> _disconnect;


private TaskCompletionSource<bool> _connectionPromise, _readyPromise; private TaskCompletionSource<bool> _connectionPromise, _readyPromise;
private CancellationTokenSource _combinedCancelToken, _reconnectCancelToken, _connectionCancelToken; private CancellationTokenSource _combinedCancelToken, _reconnectCancelToken, _connectionCancelToken;
@@ -26,14 +28,14 @@ namespace Discord
public ConnectionState State { get; private set; } public ConnectionState State { get; private set; }
public CancellationToken CancelToken { get; private set; } public CancellationToken CancelToken { get; private set; }


internal ConnectionManager(SemaphoreSlim stateLock, Logger logger, int connectionTimeout,
Func<Task> onConnecting, Func<Exception, Task> onDisconnecting, Action<Func<Exception, Task>> clientDisconnectHandler)
internal ConnectionManager(SemaphoreSlim stateLock, Logger logger, int connectionTimeout,
Func<Task> connect, Func<Exception, Task> disconnect, Action<Func<Exception, Task>> clientDisconnectHandler)
{ {
_stateLock = stateLock; _stateLock = stateLock;
_logger = logger; _logger = logger;
_connectionTimeout = connectionTimeout; _connectionTimeout = connectionTimeout;
_onConnecting = onConnecting;
_onDisconnecting = onDisconnecting;
_connect = connect;
_disconnect = disconnect;


clientDisconnectHandler(ex => clientDisconnectHandler(ex =>
{ {
@@ -67,16 +69,16 @@ namespace Discord
try try
{ {
await ConnectAsync(reconnectCancelToken).ConfigureAwait(false); await ConnectAsync(reconnectCancelToken).ConfigureAwait(false);
nextReconnectDelay = 1000; //Reset delay
nextReconnectDelay = 1000; //Reset delay
await _connectionPromise.Task.ConfigureAwait(false); await _connectionPromise.Task.ConfigureAwait(false);
} }
catch (OperationCanceledException ex)
{
catch (OperationCanceledException ex)
{
Cancel(); //In case this exception didn't come from another Error call Cancel(); //In case this exception didn't come from another Error call
await DisconnectAsync(ex, !reconnectCancelToken.IsCancellationRequested).ConfigureAwait(false); await DisconnectAsync(ex, !reconnectCancelToken.IsCancellationRequested).ConfigureAwait(false);
} }
catch (Exception ex)
{
catch (Exception ex)
{
Error(ex); //In case this exception didn't come from another Error call Error(ex); //In case this exception didn't come from another Error call
if (!reconnectCancelToken.IsCancellationRequested) if (!reconnectCancelToken.IsCancellationRequested)
{ {
@@ -120,9 +122,11 @@ namespace Discord
_connectionPromise = new TaskCompletionSource<bool>(); _connectionPromise = new TaskCompletionSource<bool>();
State = ConnectionState.Connecting; State = ConnectionState.Connecting;
await _logger.InfoAsync("Connecting").ConfigureAwait(false); await _logger.InfoAsync("Connecting").ConfigureAwait(false);
try try
{ {
await _connectingEvent.InvokeAsync().ConfigureAwait(false);

var readyPromise = new TaskCompletionSource<bool>(); var readyPromise = new TaskCompletionSource<bool>();
_readyPromise = readyPromise; _readyPromise = readyPromise;


@@ -138,7 +142,7 @@ namespace Discord
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
}); });


await _onConnecting().ConfigureAwait(false);
await _connect().ConfigureAwait(false);


await _logger.InfoAsync("Connected").ConfigureAwait(false); await _logger.InfoAsync("Connected").ConfigureAwait(false);
State = ConnectionState.Connected; State = ConnectionState.Connected;
@@ -157,7 +161,7 @@ namespace Discord
State = ConnectionState.Disconnecting; State = ConnectionState.Disconnecting;
await _logger.InfoAsync("Disconnecting").ConfigureAwait(false); await _logger.InfoAsync("Disconnecting").ConfigureAwait(false);


await _onDisconnecting(ex).ConfigureAwait(false);
await _disconnect(ex).ConfigureAwait(false);


await _logger.InfoAsync("Disconnected").ConfigureAwait(false); await _logger.InfoAsync("Disconnected").ConfigureAwait(false);
State = ConnectionState.Disconnected; State = ConnectionState.Disconnected;
@@ -207,4 +211,4 @@ namespace Discord
} }
} }
} }
}
}

+ 6
- 0
src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs View File

@@ -7,6 +7,12 @@ namespace Discord.WebSocket
public partial class DiscordSocketClient public partial class DiscordSocketClient
{ {
//General //General
public event Func<Task> Connecting
{
add { _connectingEvent.Add(value); }
remove { _connectingEvent.Remove(value); }
}
private readonly AsyncEvent<Func<Task>> _connectingEvent = new AsyncEvent<Func<Task>>();
public event Func<Task> Connected public event Func<Task> Connected
{ {
add { _connectedEvent.Add(value); } add { _connectedEvent.Add(value); }


+ 22
- 21
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -63,9 +63,9 @@ namespace Discord.WebSocket
public new SocketSelfUser CurrentUser { get => base.CurrentUser as SocketSelfUser; private set => base.CurrentUser = value; } public new SocketSelfUser CurrentUser { get => base.CurrentUser as SocketSelfUser; private set => base.CurrentUser = value; }
public IReadOnlyCollection<SocketGuild> Guilds => State.Guilds; public IReadOnlyCollection<SocketGuild> Guilds => State.Guilds;
public IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels; public IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels;
public IReadOnlyCollection<SocketDMChannel> DMChannels
public IReadOnlyCollection<SocketDMChannel> DMChannels
=> State.PrivateChannels.Select(x => x as SocketDMChannel).Where(x => x != null).ToImmutableArray(); => State.PrivateChannels.Select(x => x as SocketDMChannel).Where(x => x != null).ToImmutableArray();
public IReadOnlyCollection<SocketGroupChannel> GroupChannels
public IReadOnlyCollection<SocketGroupChannel> GroupChannels
=> State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray(); => State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray();
public IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection(); public IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection();


@@ -90,11 +90,12 @@ namespace Discord.WebSocket


_stateLock = new SemaphoreSlim(1, 1); _stateLock = new SemaphoreSlim(1, 1);
_gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}"); _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}");
_connection = new ConnectionManager(_stateLock, _gatewayLogger, config.ConnectionTimeout,
OnConnectingAsync, OnDisconnectingAsync, x => ApiClient.Disconnected += x);
_connection = new ConnectionManager(_stateLock, _gatewayLogger, config.ConnectionTimeout,
ConnectAsync, DisconnectAsync, x => ApiClient.Disconnected += x);
_connection.Connecting += () => TimedInvokeAsync(_connectingEvent, nameof(Connecting));
_connection.Connected += () => TimedInvokeAsync(_connectedEvent, nameof(Connected)); _connection.Connected += () => TimedInvokeAsync(_connectedEvent, nameof(Connected));
_connection.Disconnected += (ex, recon) => TimedInvokeAsync(_disconnectedEvent, nameof(Disconnected), ex); _connection.Disconnected += (ex, recon) => TimedInvokeAsync(_disconnectedEvent, nameof(Disconnected), ex);
_nextAudioId = 1; _nextAudioId = 1;
_connectionGroupLock = groupLock; _connectionGroupLock = groupLock;
_parentClient = parentClient; _parentClient = parentClient;
@@ -105,7 +106,7 @@ namespace Discord.WebSocket
_gatewayLogger.WarningAsync("Serializer Error", e.ErrorContext.Error).GetAwaiter().GetResult(); _gatewayLogger.WarningAsync("Serializer Error", e.ErrorContext.Error).GetAwaiter().GetResult();
e.ErrorContext.Handled = true; e.ErrorContext.Handled = true;
}; };
ApiClient.SentGatewayMessage += async opCode => await _gatewayLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); ApiClient.SentGatewayMessage += async opCode => await _gatewayLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false);
ApiClient.ReceivedGatewayEvent += ProcessMessageAsync; ApiClient.ReceivedGatewayEvent += ProcessMessageAsync;


@@ -137,7 +138,7 @@ namespace Discord.WebSocket
ApiClient.Dispose(); ApiClient.Dispose();
} }
} }
internal override async Task OnLoginAsync(TokenType tokenType, string token) internal override async Task OnLoginAsync(TokenType tokenType, string token)
{ {
if (_parentClient == null) if (_parentClient == null)
@@ -155,12 +156,12 @@ namespace Discord.WebSocket
_voiceRegions = ImmutableDictionary.Create<string, RestVoiceRegion>(); _voiceRegions = ImmutableDictionary.Create<string, RestVoiceRegion>();
} }


public async Task StartAsync()
public async Task StartAsync()
=> await _connection.StartAsync().ConfigureAwait(false); => await _connection.StartAsync().ConfigureAwait(false);
public async Task StopAsync()
public async Task StopAsync()
=> await _connection.StopAsync().ConfigureAwait(false); => await _connection.StopAsync().ConfigureAwait(false);
private async Task OnConnectingAsync()
private async Task ConnectAsync()
{ {
if (_connectionGroupLock != null) if (_connectionGroupLock != null)
await _connectionGroupLock.WaitAsync(_connection.CancelToken).ConfigureAwait(false); await _connectionGroupLock.WaitAsync(_connection.CancelToken).ConfigureAwait(false);
@@ -182,11 +183,11 @@ namespace Discord.WebSocket


//Wait for READY //Wait for READY
await _connection.WaitAsync().ConfigureAwait(false); await _connection.WaitAsync().ConfigureAwait(false);
await _gatewayLogger.DebugAsync("Sending Status").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Sending Status").ConfigureAwait(false);
await SendStatusAsync().ConfigureAwait(false); await SendStatusAsync().ConfigureAwait(false);
} }
finally
finally
{ {
if (_connectionGroupLock != null) if (_connectionGroupLock != null)
{ {
@@ -195,7 +196,7 @@ namespace Discord.WebSocket
} }
} }
} }
private async Task OnDisconnectingAsync(Exception ex)
private async Task DisconnectAsync(Exception ex)
{ {


await _gatewayLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false);
@@ -232,7 +233,7 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
public async Task<RestApplication> GetApplicationInfoAsync() public async Task<RestApplication> GetApplicationInfoAsync()
{
{
return _applicationInfo ?? (_applicationInfo = await ClientHelper.GetApplicationInfoAsync(this, new RequestOptions())); return _applicationInfo ?? (_applicationInfo = await ClientHelper.GetApplicationInfoAsync(this, new RequestOptions()));
} }


@@ -391,7 +392,7 @@ namespace Discord.WebSocket
if (seq != null) if (seq != null)
_lastSeq = seq.Value; _lastSeq = seq.Value;
_lastMessageTime = Environment.TickCount; _lastMessageTime = Environment.TickCount;
try try
{ {
switch (opCode) switch (opCode)
@@ -407,7 +408,7 @@ namespace Discord.WebSocket
case GatewayOpCode.Heartbeat: case GatewayOpCode.Heartbeat:
{ {
await _gatewayLogger.DebugAsync("Received Heartbeat").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Heartbeat").ConfigureAwait(false);
await ApiClient.SendHeartbeatAsync(_lastSeq).ConfigureAwait(false); await ApiClient.SendHeartbeatAsync(_lastSeq).ConfigureAwait(false);
} }
break; break;
@@ -498,7 +499,7 @@ namespace Discord.WebSocket
} }
else if (_connection.CancelToken.IsCancellationRequested) else if (_connection.CancelToken.IsCancellationRequested)
return; return;
await TimedInvokeAsync(_readyEvent, nameof(Ready)).ConfigureAwait(false); await TimedInvokeAsync(_readyEvent, nameof(Ready)).ConfigureAwait(false);
await _gatewayLogger.InfoAsync("Ready").ConfigureAwait(false); await _gatewayLogger.InfoAsync("Ready").ConfigureAwait(false);
}); });
@@ -537,7 +538,7 @@ namespace Discord.WebSocket
if (guild != null) if (guild != null)
{ {
guild.Update(State, data); guild.Update(State, data);
if (_unavailableGuildCount != 0) if (_unavailableGuildCount != 0)
_unavailableGuildCount--; _unavailableGuildCount--;
await GuildAvailableAsync(guild).ConfigureAwait(false); await GuildAvailableAsync(guild).ConfigureAwait(false);
@@ -1050,7 +1051,7 @@ namespace Discord.WebSocket


SocketUser user = guild.GetUser(data.User.Id); SocketUser user = guild.GetUser(data.User.Id);
if (user == null) if (user == null)
user = SocketUnknownUser.Create(this, State, data.User);
user = SocketUnknownUser.Create(this, State, data.User);
await TimedInvokeAsync(_userBannedEvent, nameof(UserBanned), user, guild).ConfigureAwait(false); await TimedInvokeAsync(_userBannedEvent, nameof(UserBanned), user, guild).ConfigureAwait(false);
} }
else else
@@ -1348,7 +1349,7 @@ namespace Discord.WebSocket
await TimedInvokeAsync(_userUpdatedEvent, nameof(UserUpdated), globalBefore, user).ConfigureAwait(false); await TimedInvokeAsync(_userUpdatedEvent, nameof(UserUpdated), globalBefore, user).ConfigureAwait(false);
} }
} }
var before = user.Clone(); var before = user.Clone();
user.Update(State, data, true); user.Update(State, data, true);
await TimedInvokeAsync(_guildMemberUpdatedEvent, nameof(GuildMemberUpdated), before, user).ConfigureAwait(false); await TimedInvokeAsync(_guildMemberUpdatedEvent, nameof(GuildMemberUpdated), before, user).ConfigureAwait(false);


Loading…
Cancel
Save