private void Dispose(bool disposing) { if (_disposed) { return; } if (disposing) { _httpClient?.Dispose(); RateLimiter?.Dispose(); } _disposed = true; }
/// <summary> /// Constructor. /// </summary> /// <param name="rateLimiter">The rate limiter (auto configured).</param> /// <param name="options">The options.</param> /// <param name="logger">The logger.</param> internal BinanceHttpClient(IApiRateLimiter rateLimiter = null, IOptions <BinanceApiOptions> options = null, ILogger <BinanceHttpClient> logger = null) { RateLimiter = rateLimiter ?? new ApiRateLimiter(); Options = options?.Value ?? new BinanceApiOptions(); _logger = logger; // Configure request rate limiter. RateLimiter.Configure(TimeSpan.FromMinutes(Options.RequestRateLimit.DurationMinutes), Options.RequestRateLimit.Count); // Configure request burst rate limiter. RateLimiter.Configure(TimeSpan.FromSeconds(Options.RequestRateLimit.BurstDurationSeconds), Options.RequestRateLimit.BurstCount); _httpClient = new HttpClient { BaseAddress = new Uri(EndpointUrl) }; var version = GetType().Assembly.GetName().Version; var versionString = $"{version.Major}.{version.Minor}.{version.Build}{(version.Revision > 0 ? $".{version.Revision}" : string.Empty)}"; _httpClient.DefaultRequestHeaders.Add("User-Agent", $"Binance/{versionString} (.NET; +https://github.com/sonvister/Binance)"); }
/// <summary> /// Constructor. /// </summary> /// <param name="timestampProvider">The timestamp provider.</param> /// <param name="rateLimiter">The rate limiter (auto configured).</param> /// <param name="options">The options.</param> /// <param name="logger">The logger.</param> internal BinanceHttpClient(ITimestampProvider timestampProvider = null, IApiRateLimiter rateLimiter = null, IOptions <BinanceApiOptions> options = null, ILogger <BinanceHttpClient> logger = null) : base(logger) { TimestampProvider = timestampProvider ?? new TimestampProvider(); RateLimiter = rateLimiter ?? new ApiRateLimiter(); _options = options?.Value ?? new BinanceApiOptions(); DefaultRecvWindow = _options.RecvWindowDefault ?? default; TimestampProvider.TimestampOffsetRefreshPeriod = TimeSpan.FromMinutes(_options.TimestampOffsetRefreshPeriodMinutes); try { // Configure request rate limiter. RateLimiter.Configure(TimeSpan.FromMinutes(_options.RequestRateLimit.DurationMinutes), _options.RequestRateLimit.Count); // Configure request burst rate limiter. RateLimiter.Configure(TimeSpan.FromSeconds(_options.RequestRateLimit.BurstDurationSeconds), _options.RequestRateLimit.BurstCount); } catch (Exception e) { var message = $"{nameof(BinanceHttpClient)}: Failed to configure request rate limiter."; Logger?.LogError(e, message); throw new BinanceApiException(message, e); } var uri = new Uri(EndpointUrl); try { _httpClient = new HttpClient { BaseAddress = uri, Timeout = TimeSpan.FromSeconds(_options.HttpClientTimeoutDefaultSeconds) }; } catch (Exception e) { var message = $"{nameof(BinanceHttpClient)}: Failed to create HttpClient."; Logger?.LogError(e, message); throw new BinanceApiException(message, e); } if (_options.ServicePointManagerConnectionLeaseTimeoutMilliseconds > 0) { try { // FIX: Singleton HttpClient doesn't respect DNS changes. // https://github.com/dotnet/corefx/issues/11224 var sp = ServicePointManager.FindServicePoint(uri); sp.ConnectionLeaseTimeout = _options.ServicePointManagerConnectionLeaseTimeoutMilliseconds; } catch (Exception e) { var message = $"{nameof(BinanceHttpClient)}: Failed to set {nameof(ServicePointManager)}.ConnectionLeaseTimeout."; Logger?.LogError(e, message); throw new BinanceApiException(message, e); } } try { var version = GetType().Assembly.GetName().Version; var versionString = $"{version.Major}.{version.Minor}.{version.Build}{(version.Revision > 0 ? $".{version.Revision}" : string.Empty)}"; _httpClient.DefaultRequestHeaders.Add("User-Agent", $"Binance/{versionString} (.NET; +https://github.com/sonvister/Binance)"); } catch (Exception e) { var message = $"{nameof(BinanceHttpClient)}: Failed to set User-Agent."; Logger?.LogError(e, message); throw new BinanceApiException(message, e); } }