Browse Source

Added Proxy support, split DiscordWebSocketClientConfig into DiscordAPIClientConfig

tags/docs-0.9
RogueException 9 years ago
parent
commit
98bad63957
10 changed files with 90 additions and 58 deletions
  1. +3
    -0
      src/Discord.Net.Net45/Discord.Net.csproj
  2. +5
    -2
      src/Discord.Net/DiscordAPIClient.cs
  3. +50
    -0
      src/Discord.Net/DiscordAPIClientConfig.cs
  4. +1
    -2
      src/Discord.Net/DiscordClient.cs
  5. +1
    -1
      src/Discord.Net/DiscordClientConfig.cs
  6. +3
    -29
      src/Discord.Net/DiscordWebSocketClientConfig.cs
  7. +7
    -5
      src/Discord.Net/Net/RestClient.SharpRest.cs
  8. +11
    -11
      src/Discord.Net/Net/RestClient.cs
  9. +8
    -7
      src/Discord.Net/Net/WebSocket.WebSocketSharp.cs
  10. +1
    -1
      src/Discord.Net/Net/WebSocket.cs

+ 3
- 0
src/Discord.Net.Net45/Discord.Net.csproj View File

@@ -151,6 +151,9 @@
<Compile Include="..\Discord.Net\DiscordAPIClient.cs">
<Link>DiscordAPIClient.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DiscordAPIClientConfig.cs">
<Link>DiscordAPIClientConfig.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DiscordClient.API.cs">
<Link>DiscordClient.API.cs</Link>
</Compile>


+ 5
- 2
src/Discord.Net/DiscordAPIClient.cs View File

@@ -11,12 +11,15 @@ namespace Discord
/// <summary> A lightweight wrapper around the Discord API. </summary>
public class DiscordAPIClient
{
private readonly DiscordAPIClientConfig _config;

internal RestClient RestClient => _rest;
private readonly RestClient _rest;

public DiscordAPIClient(LogMessageSeverity logLevel, string userAgent, int timeout)
public DiscordAPIClient(DiscordAPIClientConfig config = null)
{
_rest = new RestClient(logLevel, userAgent, timeout);
_config = config ?? new DiscordAPIClientConfig();
_rest = new RestClient(_config);
}

private string _token;


+ 50
- 0
src/Discord.Net/DiscordAPIClientConfig.cs View File

@@ -0,0 +1,50 @@
using System;
using System.Net;
using System.Reflection;

namespace Discord
{
public class DiscordAPIClientConfig
{
/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;
/// <summary> Max time (in milliseconds) to wait for an API request to complete. </summary>
public int APITimeout { get { return _apiTimeout; } set { SetValue(ref _apiTimeout, value); } }
private int _apiTimeout = 10000;

/// <summary> The proxy to user for API and WebSocket connections. </summary>
public string ProxyUrl { get { return _proxyUrl; } set { SetValue(ref _proxyUrl, value); } }
private string _proxyUrl = null;
/// <summary> The credentials to use for this proxy. </summary>
public NetworkCredential ProxyCredentials { get { return _proxyCredentials; } set { SetValue(ref _proxyCredentials, value); } }
private NetworkCredential _proxyCredentials = null;

internal string UserAgent
{
get
{
string version = typeof(DiscordClientConfig).GetTypeInfo().Assembly.GetName().Version.ToString(2);
return $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)";
}
}

//Lock
protected bool _isLocked;
internal void Lock() { _isLocked = true; }
protected void SetValue<T>(ref T storage, T value)
{
if (_isLocked)
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
storage = value;
}

public DiscordAPIClientConfig Clone()
{
var config = MemberwiseClone() as DiscordAPIClientConfig;
config._isLocked = false;
return config;
}
}
}

+ 1
- 2
src/Discord.Net/DiscordClient.cs View File

@@ -55,7 +55,7 @@ namespace Discord
: base(config ?? new DiscordClientConfig())
{
_rand = new Random();
_api = new DiscordAPIClient(_config.LogLevel, _config.UserAgent, _config.APITimeout);
_api = new DiscordAPIClient(_config);
if (Config.UseMessageQueue)
_pendingMessages = new ConcurrentQueue<Message>();
if (Config.EnableVoiceMultiserver)
@@ -765,7 +765,6 @@ namespace Discord
{
var config = _config.Clone();
config.LogLevel = _config.LogLevel;// (LogMessageSeverity)Math.Min((int)_config.LogLevel, (int)LogMessageSeverity.Warning);
config.EnableVoiceMultiserver = false;
config.VoiceOnly = true;
config.VoiceClientId = unchecked(++_nextVoiceClientId);
return new DiscordWebSocketClient(config, serverId);


+ 1
- 1
src/Discord.Net/DiscordClientConfig.cs View File

@@ -25,7 +25,7 @@

public new DiscordClientConfig Clone()
{
var config = this.MemberwiseClone() as DiscordClientConfig;
var config = MemberwiseClone() as DiscordClientConfig;
config._isLocked = false;
return config;
}


+ 3
- 29
src/Discord.Net/DiscordWebSocketClientConfig.cs View File

@@ -12,12 +12,8 @@ namespace Discord
Both = Outgoing | Incoming
}

public class DiscordWebSocketClientConfig
public class DiscordWebSocketClientConfig : DiscordAPIClientConfig
{
/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;

/// <summary> Max time in milliseconds to wait for DiscordClient to connect and initialize. </summary>
public int ConnectionTimeout { get { return _connectionTimeout; } set { SetValue(ref _connectionTimeout, value); } }
private int _connectionTimeout = 30000;
@@ -27,9 +23,6 @@ namespace Discord
/// <summary> Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying. </summary>
public int FailedReconnectDelay { get { return _failedReconnectDelay; } set { SetValue(ref _failedReconnectDelay, value); } }
private int _failedReconnectDelay = 10000;
/// <summary> Max time (in milliseconds) to wait for an API request to complete. </summary>
public int APITimeout { get { return _apiTimeout; } set { SetValue(ref _apiTimeout, value); } }
private int _apiTimeout = 10000;

/// <summary> Gets or sets the time (in milliseconds) to wait when the websocket's message queue is empty before checking again. </summary>
public int WebSocketInterval { get { return _webSocketInterval; } set { SetValue(ref _webSocketInterval, value); } }
@@ -54,28 +47,9 @@ namespace Discord

internal virtual bool EnableVoice => _voiceMode != DiscordVoiceMode.Disabled;

internal string UserAgent
{
get
{
string version = typeof(DiscordClientConfig).GetTypeInfo().Assembly.GetName().Version.ToString(2);
return $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)";
}
}

//Lock
protected bool _isLocked;
internal void Lock() { _isLocked = true; }
protected void SetValue<T>(ref T storage, T value)
{
if (_isLocked)
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
storage = value;
}

public DiscordClientConfig Clone()
public new DiscordWebSocketClientConfig Clone()
{
var config = this.MemberwiseClone() as DiscordClientConfig;
var config = MemberwiseClone() as DiscordWebSocketClientConfig;
config._isLocked = false;
return config;
}


+ 7
- 5
src/Discord.Net/Net/RestClient.SharpRest.cs View File

@@ -1,6 +1,7 @@
using Discord.API;
using RestSharp;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
@@ -11,18 +12,19 @@ namespace Discord.Net
{
private RestSharp.RestClient _client;

partial void Initialize(string userAgent, int timeout)
partial void Initialize()
{
_client = new RestSharp.RestClient(Endpoints.BaseApi)
{
PreAuthenticate = false
PreAuthenticate = false,
Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials),
ReadWriteTimeout = _config.APITimeout,
UserAgent = _config.UserAgent
};
_client.RemoveDefaultParameter("Accept");
_client.AddDefaultHeader("accept", "*/*");
_client.AddDefaultHeader("accept-encoding", "gzip,deflate");
_client.UserAgent = userAgent;
_client.ReadWriteTimeout = timeout;
}
}

internal void SetToken(string token)
{


+ 11
- 11
src/Discord.Net/Net/RestClient.cs View File

@@ -10,15 +10,15 @@ namespace Discord.Net
{
internal partial class RestClient
{
private readonly LogMessageSeverity _logLevel;
private readonly DiscordAPIClientConfig _config;
private CancellationToken _cancelToken;

public RestClient(LogMessageSeverity logLevel, string userAgent, int timeout)
public RestClient(DiscordAPIClientConfig config)
{
_logLevel = logLevel;
Initialize(userAgent, timeout);
_config = config;
Initialize();
}
partial void Initialize(string userAgent, int timeout);
partial void Initialize();

//DELETE
private static readonly HttpMethod _delete = HttpMethod.Delete;
@@ -90,7 +90,7 @@ namespace Discord.Net
if (content != null)
requestJson = JsonConvert.SerializeObject(content);

if (_logLevel >= LogMessageSeverity.Verbose)
if (_config.LogLevel >= LogMessageSeverity.Verbose)
stopwatch = Stopwatch.StartNew();
string responseJson = await SendInternal(method, path, requestJson, _cancelToken).ConfigureAwait(false);
@@ -100,10 +100,10 @@ namespace Discord.Net
throw new Exception("API check failed: Response is not empty.");
#endif

if (_logLevel >= LogMessageSeverity.Verbose)
if (_config.LogLevel >= LogMessageSeverity.Verbose)
{
stopwatch.Stop();
if (content != null && _logLevel >= LogMessageSeverity.Debug)
if (content != null && _config.LogLevel >= LogMessageSeverity.Debug)
{
if (path.StartsWith(Endpoints.Auth))
RaiseOnRequest(method, path, "[Hidden]", stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
@@ -129,7 +129,7 @@ namespace Discord.Net
{
Stopwatch stopwatch = null;

if (_logLevel >= LogMessageSeverity.Verbose)
if (_config.LogLevel >= LogMessageSeverity.Verbose)
stopwatch = Stopwatch.StartNew();
string responseJson = await SendFileInternal(method, path, filePath, _cancelToken).ConfigureAwait(false);
@@ -139,10 +139,10 @@ namespace Discord.Net
throw new Exception("API check failed: Response is not empty.");
#endif

if (_logLevel >= LogMessageSeverity.Verbose)
if (_config.LogLevel >= LogMessageSeverity.Verbose)
{
stopwatch.Stop();
if (_logLevel >= LogMessageSeverity.Debug)
if (_config.LogLevel >= LogMessageSeverity.Debug)
RaiseOnRequest(method, path, filePath, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
else
RaiseOnRequest(method, path, null, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);


+ 8
- 7
src/Discord.Net/Net/WebSocket.WebSocketSharp.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using WSSharpNWebSocket = WebSocketSharp.WebSocket;
@@ -9,9 +10,8 @@ namespace Discord.Net
{
internal class WSSharpWebSocketEngine : IWebSocketEngine
{
private readonly DiscordWebSocketClientConfig _config;
private readonly ConcurrentQueue<string> _sendQueue;
private readonly int _sendInterval;
private readonly string _userAgent;
private readonly WebSocket _parent;
private WSSharpNWebSocket _webSocket;

@@ -22,11 +22,10 @@ namespace Discord.Net
ProcessMessage(this, new WebSocketMessageEventArgs(msg));
}

internal WSSharpWebSocketEngine(WebSocket parent, string userAgent, int sendInterval)
internal WSSharpWebSocketEngine(WebSocket parent, DiscordWebSocketClientConfig config)
{
_parent = parent;
_userAgent = userAgent;
_sendInterval = sendInterval;
_config = config;
_sendQueue = new ConcurrentQueue<string>();
}

@@ -35,7 +34,8 @@ namespace Discord.Net
_webSocket = new WSSharpNWebSocket(host);
_webSocket.EmitOnPing = false;
_webSocket.EnableRedirection = true;
_webSocket.Compression = WebSocketSharp.CompressionMethod.None;
_webSocket.Compression = WebSocketSharp.CompressionMethod.None;
_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials.UserName, _config.ProxyCredentials.Password);
_webSocket.OnMessage += (s, e) => RaiseProcessMessage(e.Data);
_webSocket.OnError += async (s, e) =>
{
@@ -77,6 +77,7 @@ namespace Discord.Net

private Task SendAsync(CancellationToken cancelToken)
{
var sendInterval = _config.WebSocketInterval;
return Task.Run(async () =>
{
try
@@ -86,7 +87,7 @@ namespace Discord.Net
string json;
while (_sendQueue.TryDequeue(out json))
_webSocket.Send(json);
await Task.Delay(_sendInterval, cancelToken).ConfigureAwait(false);
await Task.Delay(sendInterval, cancelToken).ConfigureAwait(false);
}
}
catch (OperationCanceledException) { }


+ 1
- 1
src/Discord.Net/Net/WebSocket.cs View File

@@ -65,7 +65,7 @@ namespace Discord.Net
_cancelToken = new CancellationToken(true);
_connectedEvent = new ManualResetEventSlim(false);
_engine = new WSSharpWebSocketEngine(this, client.Config.UserAgent, client.Config.WebSocketInterval);
_engine = new WSSharpWebSocketEngine(this, client.Config);
_engine.ProcessMessage += async (s, e) =>
{
if (_logLevel >= LogMessageSeverity.Debug)


Loading…
Cancel
Save