예제 #1
0
        public async ValueTask BStart(CancellationToken cancelToken, string symbol)
        {
            BNLogger.SNG.WriteO(this, $"bpolling service start...");

            if (__bnconfig.UsePollingTicker == true)
            {
                PollingTasks.Add(Task.Run(async() =>
                {
                    var _client = CreateJsonClient(publicApi.publicClient.ApiUrl);

                    var _b_params              = new Dictionary <string, object>();
                    var _b_request             = CreateJsonRequest($"/ticker/bookTicker", _b_params);
                    var _last_limit_milli_secs = 0L;

                    while (true)
                    {
                        try
                        {
                            await Task.Delay(0);

                            var _waiting_milli_secs = (CUnixTime.NowMilli - __bnconfig.PollingPrevTime) / __bnconfig.PollingTermTime;
                            if (_waiting_milli_secs == _last_limit_milli_secs)
                            {
                                var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                if (_waiting == true)
                                {
                                    break;
                                }

                                await Task.Delay(10);
                                continue;
                            }

                            _last_limit_milli_secs = _waiting_milli_secs;

                            // ticker
                            var _b_json_value = await RestExecuteAsync(_client, _b_request);
                            if (_b_json_value.IsSuccessful && _b_json_value.Content[0] == '[')
                            {
                                var _b_json_data = JsonConvert.DeserializeObject <List <BTickerItem> >(_b_json_value.Content);

                                var _tickers = new STickers
                                {
                                    exchange     = BNLogger.SNG.exchange_name,
                                    stream       = "ticker",
                                    sequentialId = _last_limit_milli_secs,
                                    result       = _b_json_data.Where(t => t.symbol == symbol).ToList <STickerItem>()
                                };

                                var _b_json_content = JsonConvert.SerializeObject(_tickers);
                                Processing.SendReceiveQ(new QMessage {
                                    command = "AP", payload = _b_json_content
                                });
                            }
                            else
                            {
                                var _http_status = (int)_b_json_value.StatusCode;
                                if (_http_status == 403 || _http_status == 418 || _http_status == 429)
                                {
                                    BNLogger.SNG.WriteQ(this, $"request-limit: https_status => {_http_status}");

                                    var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                    if (_waiting == true)
                                    {
                                        break;
                                    }

                                    await Task.Delay(1000);     // waiting 1 second
                                }
                            }
                        }
                        catch (TaskCanceledException)
                        {
                        }
                        catch (Exception ex)
                        {
                            BNLogger.SNG.WriteX(this, ex.ToString());
                        }
                        //finally
                        {
                            if (cancelToken.IsCancellationRequested == true)
                            {
                                break;
                            }
                        }

                        var _cancelled = cancelToken.WaitHandle.WaitOne(0);
                        if (_cancelled == true)
                        {
                            break;
                        }
                    }
                },
                                          cancelToken
                                          ));
            }

            await Task.WhenAll(PollingTasks);

            BNLogger.SNG.WriteO(this, $"bpolling service stop...");
        }
예제 #2
0
        public async ValueTask OStart(CancellationToken cancelToken, string symbol)
        {
            BNLogger.SNG.WriteO(this, $"polling service start: symbol => {symbol}...");

            if (__bnconfig.UsePollingTicker == false)
            {
                PollingTasks.Add(Task.Run(async() =>
                {
                    var _client = CreateJsonClient(publicApi.publicClient.ApiUrl);

                    var _o_params = new Dictionary <string, object>();
                    {
                        _o_params.Add("symbol", symbol.ToUpper());
                        _o_params.Add("limit", 20);
                    }

                    var _o_request             = CreateJsonRequest($"/depth", _o_params);
                    var _last_limit_milli_secs = 0L;

                    while (true)
                    {
                        try
                        {
                            await Task.Delay(0);

                            var _waiting_milli_secs = (CUnixTime.NowMilli - __bnconfig.PollingPrevTime) / __bnconfig.PollingTermTime;
                            if (_waiting_milli_secs == _last_limit_milli_secs)
                            {
                                var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                if (_waiting == true)
                                {
                                    break;
                                }

                                await Task.Delay(10);
                            }
                            else
                            {
                                _last_limit_milli_secs = _waiting_milli_secs;

                                // orderbook
                                var _o_json_value = await RestExecuteAsync(_client, _o_request);
                                if (_o_json_value.IsSuccessful && _o_json_value.Content[0] == '{')
                                {
                                    var _o_json_data    = JsonConvert.DeserializeObject <BAOrderBookItem>(_o_json_value.Content);
                                    _o_json_data.symbol = symbol;
                                    _o_json_data.lastId = _last_limit_milli_secs;

                                    var _orderbook = new BAOrderBook
                                    {
                                        stream = "orderbook",
                                        data   = _o_json_data
                                    };

                                    var _o_json_content = JsonConvert.SerializeObject(_orderbook);
                                    Processing.SendReceiveQ(new QMessage {
                                        command = "AP", payload = _o_json_content
                                    });
                                }
                                else
                                {
                                    var _http_status = (int)_o_json_value.StatusCode;
                                    if (_http_status == 403 || _http_status == 418 || _http_status == 429)
                                    {
                                        BNLogger.SNG.WriteQ(this, $"request-limit: symbol => {symbol}, https_status => {_http_status}");

                                        var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                        if (_waiting == true)
                                        {
                                            break;
                                        }

                                        await Task.Delay(1000);     // waiting 1 second
                                    }
                                }
                            }
                        }
                        catch (TaskCanceledException)
                        {
                        }
                        catch (Exception ex)
                        {
                            BNLogger.SNG.WriteX(this, ex.ToString());
                        }
                        //finally
                        {
                            //__semaphore.Release();

                            if (cancelToken.IsCancellationRequested == true)
                            {
                                break;
                            }
                        }

                        var _cancelled = cancelToken.WaitHandle.WaitOne(0);
                        if (_cancelled == true)
                        {
                            break;
                        }
                    }
                },
                                          cancelToken
                                          ));
            }

            await Task.WhenAll(PollingTasks);

            BNLogger.SNG.WriteO(this, $"polling service stopped: symbol => {symbol}...");
        }
예제 #3
0
        public async ValueTask Start(CancellationToken cancelToken, string symbol)
        {
            BNLogger.SNG.WriteO(this, $"pushing service start: symbol => {symbol}...");

            using (var _cws = new ClientWebSocket())
            {
                var _sending = Task.Run(async() =>
                {
                    while (true)
                    {
                        try
                        {
                            await Task.Delay(0);

                            var _waiting_time = CUnixTime.NowMilli - __last_receive_time;
                            if (_waiting_time > __bnconfig.WebSocketRetry * 1000)
                            {
                                __last_receive_time = CUnixTime.NowMilli;
                                await Open(cancelToken, _cws, symbol);

                                BNLogger.SNG.WriteO(this, $"pushing open: symbol => {symbol}...");
                            }

                            var _message = (QMessage)null;

                            if (CommandQ.TryDequeue(out _message) == false)
                            {
                                var _cancelled = cancelToken.WaitHandle.WaitOne(0);
                                if (_cancelled == true)
                                {
                                    break;
                                }

                                await Task.Delay(10);
                            }
                            else
                            {
                                await SendAsync(cancelToken, _cws, _message.payload);
                            }
                        }
                        catch (TaskCanceledException)
                        {
                        }
                        catch (Exception ex)
                        {
                            BNLogger.SNG.WriteX(this, ex.ToString());
                        }
                        //finally
                        {
                            if (_cws.State != WebSocketState.Open)
                            {
                                BNLogger.SNG.WriteO(this, $"disconnect from server(cmd): symbol => {symbol}...");
                                //cancelToken.Cancel();
                                break;
                            }

                            if (cancelToken.IsCancellationRequested == true)
                            {
                                break;
                            }
                        }
                    }
                },
                                        cancelToken
                                        );

                var _receiving = Task.Run(async() =>
                {
                    var _buffer_size = 1024 * 16;
                    var _buffer      = new byte[_buffer_size];

                    var _offset = 0;
                    var _free   = _buffer.Length;

                    while (true)
                    {
                        try
                        {
                            if (_cws.State == WebSocketState.None || _cws.State == WebSocketState.Connecting)
                            {
                                await Task.Delay(1000);
                                continue;
                            }

                            var _result = await _cws.ReceiveAsync(new ArraySegment <byte>(_buffer, _offset, _free), cancelToken);

                            _offset += _result.Count;
                            _free   -= _result.Count;

                            if (_result.EndOfMessage == false)
                            {
                                if (_free == 0)
                                {
                                    Array.Resize(ref _buffer, _buffer.Length + _buffer_size);
                                    _free = _buffer.Length - _offset;
                                }

                                continue;
                            }

                            __last_receive_time = CUnixTime.NowMilli;

                            if (_result.MessageType == WebSocketMessageType.Text)
                            {
                                var _json     = Encoding.UTF8.GetString(_buffer, 0, _offset);
                                var _selector = JsonConvert.DeserializeObject <QSelector>(_json);

                                var _stream = _selector.stream.Split('@')[1];
                                if (_stream == "aggTrade")
                                {
                                    _stream = "trade";
                                }
                                else if (_stream == "depth")
                                {
                                    _stream = "orderbook";
                                }

                                Processing.SendReceiveQ(new QMessage
                                {
                                    command = "WS",
                                    stream  = _stream,
                                    payload = _json
                                });
                            }
                            else if (_result.MessageType == WebSocketMessageType.Binary)
                            {
                            }
                            else if (_result.MessageType == WebSocketMessageType.Close)
                            {
                                await _cws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", cancelToken);

                                BNLogger.SNG.WriteO(this, $"receive close message from server: symbol => {symbol}...");
                                //cancelToken.Cancel();
                                break;
                            }
                        }
                        catch (TaskCanceledException)
                        {
                        }
                        catch (Exception ex)
                        {
                            BNLogger.SNG.WriteX(this, ex.ToString());
                        }
                        //finally
                        {
                            if (_cws.State != WebSocketState.Open)
                            {
                                BNLogger.SNG.WriteO(this, $"disconnect from server: symbol => {symbol}...");
                                //cancelToken.Cancel();
                                break;
                            }

                            if (cancelToken.IsCancellationRequested == true)
                            {
                                break;
                            }

                            _offset = 0;
                            _free   = _buffer.Length;
                        }
                    }
                },
                                          cancelToken
                                          );

                await Task.WhenAll(_sending, _receiving);

                BNLogger.SNG.WriteO(this, $"pushing service stopped: symbol => {symbol}...");
            }
        }