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..."); }
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}..."); }
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}..."); } }