public async ValueTask OStart(CancellationToken cancelToken, string symbol, int limit = 32) { GMLogger.SNG.WriteO(this, $"polling service start: symbol => {symbol}..."); var _t_polling = Task.Run(async() => { var _client = CreateJsonClient(publicApi.publicClient.ApiUrl); var _t_params = new Dictionary <string, object>(); { _t_params.Add("market", symbol); _t_params.Add("count", limit); } var _t_request = CreateJsonRequest($"/trades/ticks", _t_params); while (true) { try { await Task.Delay(__gmconfig.PollingSleep); // trades var _t_json_value = await RestExecuteAsync(_client, _t_request); if (_t_json_value.IsSuccessful && _t_json_value.Content[0] == '[') { Processing.SendReceiveQ(new QMessage { command = "AP", exchange = GMLogger.SNG.exchange_name, symbol = symbol, stream = "trade", action = "polling", payload = _t_json_value.Content }); } else { var _http_status = (int)_t_json_value.StatusCode; if (_http_status == 403 || _http_status == 418)// || _http_status == 429) { GMLogger.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) { GMLogger.SNG.WriteX(this, ex.ToString()); } //finally { if (cancelToken.IsCancellationRequested == true) { break; } } var _cancelled = cancelToken.WaitHandle.WaitOne(0); if (_cancelled == true) { break; } } }, cancelToken ); var _o_polling = Task.Run(async() => { var _client = CreateJsonClient(publicApi.publicClient.ApiUrl); var _o_params = new Dictionary <string, object>(); { _o_params.Add("markets", symbol); } var _o_request = CreateJsonRequest($"/orderbook", _o_params); while (true) { try { await Task.Delay(__gmconfig.PollingSleep); // orderbook var _o_json_value = await RestExecuteAsync(_client, _o_request); if (_o_json_value.IsSuccessful && _o_json_value.Content[0] == '[') { Processing.SendReceiveQ(new QMessage { command = "AP", exchange = GMLogger.SNG.exchange_name, symbol = symbol, stream = "orderbook", action = "polling", payload = _o_json_value.Content }); } else { var _http_status = (int)_o_json_value.StatusCode; if (_http_status == 403 || _http_status == 418)// || _http_status == 429) { GMLogger.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) { GMLogger.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(_t_polling, _o_polling); GMLogger.SNG.WriteO(this, $"polling service stopped: symbol => {symbol}..."); }
public async ValueTask Start(CancellationToken cancelToken, string symbol) { GMLogger.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 > __gmconfig.WebSocketRetry * 1000) { __last_receive_time = CUnixTime.NowMilli; await Open(cancelToken, _cws, symbol); GMLogger.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) { GMLogger.SNG.WriteX(this, ex.ToString()); } //finally { if (_cws.State != WebSocketState.Open) { GMLogger.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) { } else if (_result.MessageType == WebSocketMessageType.Binary) { var _json = Encoding.UTF8.GetString(_buffer, 0, _offset); var _selector = JsonConvert.DeserializeObject <QSelector>(_json); Processing.SendReceiveQ(new QMessage { command = "WS", exchange = GMLogger.SNG.exchange_name, symbol = symbol, stream = _selector.type, action = _selector.stream_type, payload = _json }); } else if (_result.MessageType == WebSocketMessageType.Close) { await _cws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", cancelToken); GMLogger.SNG.WriteO(this, $"receive close message from server: symbol => {symbol}..."); //cancelToken.Cancel(); break; } } catch (TaskCanceledException) { } catch (Exception ex) { GMLogger.SNG.WriteX(this, ex.ToString()); } //finally { if (_cws.State != WebSocketState.Open) { GMLogger.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); GMLogger.SNG.WriteO(this, $"pushing service stopped: symbol => {symbol}..."); } }
public async ValueTask BStart(CancellationToken cancelToken, string[] symbols) { GMLogger.SNG.WriteO(this, $"bpolling service start.."); var _b_polling = Task.Run(async() => { var _symbols = String.Join(",", symbols); var _client = CreateJsonClient(publicApi.publicClient.ApiUrl); var _b_params = new Dictionary <string, object>(); { _b_params.Add("markets", _symbols); } var _b_request = CreateJsonRequest($"/orderbook", _b_params); var _last_limit_milli_secs = 0L; while (true) { try { await Task.Delay(0); var _waiting_milli_secs = (CUnixTime.NowMilli - __gmconfig.PollingPrevTime) / __gmconfig.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; // orderbook var _b_json_value = await RestExecuteAsync(_client, _b_request); if (_b_json_value.IsSuccessful && _b_json_value.Content[0] == '[') { Processing.SendReceiveQ(new QMessage { command = "AP", exchange = GMLogger.SNG.exchange_name, symbol = _symbols, stream = "ticker", action = "polling", sequentialId = _last_limit_milli_secs, payload = _b_json_value.Content }); } else { var _http_status = (int)_b_json_value.StatusCode; if (_http_status == 403 || _http_status == 418)// || _http_status == 429) { GMLogger.SNG.WriteQ(this, $"request-limit: symbol => {_symbols}, https_status => {_http_status}"); var _waiting = cancelToken.WaitHandle.WaitOne(0); if (_waiting == true) { break; } await Task.Delay(__gmconfig.PollingSleep); } } } catch (TaskCanceledException) { } catch (Exception ex) { GMLogger.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(_b_polling); GMLogger.SNG.WriteO(this, $"bpolling service stopped.."); }