Example #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="api">The Binance API.</param>
        /// <param name="client">The WebSocket client.</param>
        /// <param name="options">The options.</param>
        /// <param name="logger">The logger.</param>
        public UserDataWebSocketClient(IBinanceApi api, IWebSocketStream webSocket, IOptions <UserDataWebSocketClientOptions> options = null, ILogger <UserDataWebSocketClient> logger = null)
            : base(webSocket, logger)
        {
            Throw.IfNull(api, nameof(api));
            Throw.IfNull(webSocket, nameof(webSocket));

            _api     = api;
            _options = options?.Value;

            webSocket.Client.Open += (s, e) =>
            {
                var period = _options?.KeepAliveTimerPeriod ?? KeepAliveTimerPeriodDefault;
                period = Math.Min(Math.Max(period, KeepAliveTimerPeriodMin), KeepAliveTimerPeriodMax);

                _keepAliveTimer = new Timer(OnKeepAliveTimer, CancellationToken.None, period, period);
            };

            webSocket.Client.Close += async(s, e) =>
            {
                _keepAliveTimer.Dispose();

                foreach (var _ in _listenKeys)
                {
                    await _api.UserStreamCloseAsync(_.Key, _.Value, CancellationToken.None)
                    .ConfigureAwait(false);
                }
            };
        }
Example #2
0
        public virtual async Task SubscribeAsync(IBinanceApiUser user, Action <UserDataEventArgs> callback, CancellationToken token)
        {
            Throw.IfNull(user, nameof(user));

            if (!token.CanBeCanceled)
            {
                throw new ArgumentException("Token must be capable of being in the canceled state.", nameof(token));
            }

            token.ThrowIfCancellationRequested();

            User = user;

            if (IsSubscribed)
            {
                throw new InvalidOperationException($"{nameof(UserDataWebSocketClient)} is already subscribed to a user.");
            }

            try
            {
                _listenKey = await _api.UserStreamStartAsync(user, token)
                             .ConfigureAwait(false);

                if (string.IsNullOrWhiteSpace(_listenKey))
                {
                    throw new Exception($"{nameof(IUserDataWebSocketClient)}: Failed to get listen key from API.");
                }

                var period = _options?.KeepAliveTimerPeriod ?? KeepAliveTimerPeriodDefault;
                period = Math.Min(Math.Max(period, KeepAliveTimerPeriodMin), KeepAliveTimerPeriodMax);

                _keepAliveTimer = new Timer(OnKeepAliveTimer, token, period, period);

                try
                {
                    await SubscribeToAsync(_listenKey, callback, token)
                    .ConfigureAwait(false);
                }
                finally
                {
                    _keepAliveTimer.Dispose();

                    await _api.UserStreamCloseAsync(User, _listenKey, CancellationToken.None)
                    .ConfigureAwait(false);
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}.{nameof(SubscribeAsync)}");
                    throw;
                }
            }
        }