Пример #1
0
        public PhotoTaggingProcessor()
        {
            _requestQueue          = new BufferBlock <PhotoAnalysisRequest>();
            _resultQueue           = new BufferBlock <PhotoAnalysisResult>();
            _requestQueueListeners = new List <Action>();
            _photoAnayser          = new PhotoAnayser();
            _rateLimiter           = new F0RateLimiter();

            AddListenersToQueue();
        }
Пример #2
0
        /// <summary>
        /// Construct an <see cref="IBinanceApiUser"/> instance providing an API
        /// key and optional API secret. The API secret is not required for
        /// the user stream methods, but is required for other account methods.
        /// </summary>
        /// <param name="apiKey">The user's API key.</param>
        /// <param name="apiSecret">The user's API secret (optional, but required for signing).</param>
        /// <param name="rateLimiter">The rate limiter (auto-configured).</param>
        /// <param name="options">The JSON API options.</param>
        public BinanceApiUser(string apiKey, string apiSecret = null, IApiRateLimiter rateLimiter = null, IOptions <BinanceApiOptions> options = null)
        {
            Throw.IfNullOrWhiteSpace(apiKey, nameof(apiKey));

            ApiKey = apiKey;

            if (!string.IsNullOrWhiteSpace(apiSecret))
            {
                _hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret));
            }

            RateLimiter = rateLimiter;
            var opt = options?.Value ?? new BinanceApiOptions();

            // Configure order rate limiter.
            RateLimiter?.Configure(TimeSpan.FromDays(opt.OrderRateLimit.DurationDays), opt.OrderRateLimit.Count);
            // Configure order burst rate limiter.
            RateLimiter?.Configure(TimeSpan.FromSeconds(opt.OrderRateLimit.BurstDurationSeconds), opt.OrderRateLimit.BurstCount);
        }
Пример #3
0
        /// <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)");
        }
Пример #4
0
        /// <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();
            var apiOptions = options?.Value ?? new BinanceApiOptions();

            DefaultRecvWindow = apiOptions.RecvWindowDefault ?? default;

            TimestampProvider.TimestampOffsetRefreshPeriod = TimeSpan.FromMinutes(apiOptions.TimestampOffsetRefreshPeriodMinutes);

            try
            {
                // Configure request rate limiter.
                RateLimiter.Configure(TimeSpan.FromMinutes(apiOptions.RequestRateLimit.DurationMinutes), apiOptions.RequestRateLimit.Count);
                // Configure request burst rate limiter.
                RateLimiter.Configure(TimeSpan.FromSeconds(apiOptions.RequestRateLimit.BurstDurationSeconds), apiOptions.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(apiOptions.HttpClientTimeoutDefaultSeconds)
                };
            }
            catch (Exception e)
            {
                var message = $"{nameof(BinanceHttpClient)}: Failed to create HttpClient.";
                Logger?.LogError(e, message);
                throw new BinanceApiException(message, e);
            }

            if (apiOptions.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 = apiOptions.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);
            }
        }
Пример #5
0
        private async Task <string> RequestAsync(HttpMethod method, BinanceHttpRequest request, CancellationToken token = default, IApiRateLimiter rateLimiter = null)
        {
            Throw.IfNull(request, nameof(request));

            token.ThrowIfCancellationRequested();

            var requestMessage = request.CreateMessage(method);

            _logger?.LogDebug($"{nameof(BinanceHttpClient)}.{nameof(RequestAsync)}: [{method.Method}] \"{requestMessage.RequestUri}\"");

            await(rateLimiter ?? RateLimiter).DelayAsync(request.RateLimitWeight, token)
            .ConfigureAwait(false);

            using (var response = await _httpClient.SendAsync(requestMessage, token).ConfigureAwait(false))
            {
                if (response.IsSuccessStatusCode)
                {
                    var json = await response.Content.ReadAsStringAsync()
                               .ConfigureAwait(false);

                    _logger?.LogDebug($"{nameof(BinanceHttpClient)}: \"{json}\"");

                    return(json);
                }

                if (response.StatusCode == HttpStatusCode.GatewayTimeout)
                {
                    throw new BinanceUnknownStatusException();
                }

                var error = await response.Content.ReadAsStringAsync()
                            .ConfigureAwait(false);

                var    errorCode    = 0;
                string errorMessage = null;

                // ReSharper disable once InvertIf
                if (!string.IsNullOrWhiteSpace(error) && error.IsJsonObject())
                {
                    try // to parse server error response.
                    {
                        var jObject = JObject.Parse(error);

                        errorCode    = jObject["code"]?.Value <int>() ?? 0;
                        errorMessage = jObject["msg"]?.Value <string>();
                    }
                    catch (Exception e)
                    {
                        _logger?.LogError(e, $"{nameof(BinanceHttpClient)}.{nameof(RequestAsync)} failed to parse server error response: \"{error}\"");
                    }
                }

                switch (response.StatusCode)
                {
                case (HttpStatusCode)429:
                    throw new BinanceRequestRateLimitExceededException(response.ReasonPhrase, errorCode, errorMessage);

                case (HttpStatusCode)418:
                    throw new BinanceRequestRateLimitIpBanException(response.ReasonPhrase, errorCode, errorMessage);

                default:
                    throw new BinanceHttpException(response.StatusCode, response.ReasonPhrase, errorCode, errorMessage);
                }
            }
        }
Пример #6
0
 public Task <string> DeleteAsync(BinanceHttpRequest request, CancellationToken token = default, IApiRateLimiter rateLimiter = null)
 {
     return(RequestAsync(HttpMethod.Delete, request, token, rateLimiter));
 }
Пример #7
0
 public Task <string> PutAsync(BinanceHttpRequest request, CancellationToken token = default, IApiRateLimiter rateLimiter = null)
 {
     return(RequestAsync(HttpMethod.Put, request, rateLimiter ?? RateLimiter, token));
 }