Esempio n. 1
0
        private void ProcessAckAndEvent(Packet packet)
        {
            try
            {
                using var jsonData = JsonDocument.Parse(packet.Data);
                var arrayLength = jsonData.RootElement.GetArrayLength();

                if (packet.Id.HasValue && _logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"Received packet with ACK: {packet.Id.Value}");
                }

                if (packet.SocketIoType == SocketIoType.Ack && packet.Id.HasValue)
                {
                    var data = jsonData.RootElement.EnumerateArray().ToList();
                    _client.Events.AckMessageSubject.OnNext(new AckMessageEvent(packet.Id.Value, data));
                }
                else if (arrayLength > 0)
                {
                    //first element should contain event name
                    //we can have zero, one or multiple arguments after event name so emit based on number of them
                    JsonElement?ioEvent = null;
                    var         data    = arrayLength > 1 ? new List <JsonElement>(arrayLength - 1) : EmptyList;
                    foreach (var element in jsonData.RootElement.EnumerateArray())
                    {
                        if (!ioEvent.HasValue)
                        {
                            ioEvent = element;
                        }
                        else
                        {
                            data.Add(element);
                        }
                    }

                    var message = new EventMessageEvent(ioEvent.ToString(), packet.Id.HasValue, Callback, data);
                    _client.Events.EventMessageSubject.OnNext(message);

                    void Callback(object callbackData) => _client.EmitAcknowledge(
                        packet.Id ?? throw new NotSupportedException("This message does not support acknowledgement."),
                        callbackData);
                }
                else
                {
                    _logger.LogWarning($"Unable to process ACK packet: {packet}. Data: {jsonData.RootElement}");
                    _client.Events.ErrorSubject.OnNext(new ErrorEvent($"Unable to process packet: {packet}"));
                }
            }
            catch (JsonException ex)
            {
                _logger.LogError(ex, $"Error while deserializing event message. Packet: {packet}");
                _client.Events.ErrorSubject.OnNext(new ErrorEvent(ex, "Error while deserializing event message"));
            }
        }
        private void OnMessage(EventMessageEvent e)
        {
            try
            {
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"Received message: {e.FirstData}");
                }

                var data = e.FirstData;
                if (string.IsNullOrEmpty(data))
                {
                    _logger.LogWarning("Received empty data from socket.");
                }
                else
                {
                    var prefix = ParsePrefix(data);
                    if (prefix == ICryptoCompareSubscription.CurrentPrefix)
                    {
                        try
                        {
                            if (CCC.Current.TryUnpack(data, out var current))
                            {
                                _currentSubject.OnNext(current);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Error while parsing data from CryptoCompare.");
                            _currentSubject.OnError(new CryptoCompareParseException(data, ex));
                        }
                    }
                    else if (prefix == ICryptoCompareSubscription.TradePrefix)
                    {
                        try
                        {
                            if (CCC.Trade.TryUnpack(data, out var trade))
                            {
                                _tradeSubject.OnNext(trade);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Error while parsing data from CryptoCompare.");
                            _tradeSubject.OnError(new CryptoCompareParseException(data, ex));
                        }
                    }
                    else if (prefix == ICryptoCompareSubscription.CCCAGGPrefix)
                    {
                        _logger.LogInformation($"CCCAGG data: {data}");
                    }
                    else if (prefix == ICryptoCompareSubscription.VolumePrefix)
                    {
                        try
                        {
                            if (CCC.Volume.TryUnpack(data, out var volume))
                            {
                                _volumeSubject.OnNext(volume);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Error while parsing dat from CryptoCompare.");
                            _volumeSubject.OnError(new CryptoCompareParseException(data, ex));
                        }
                    }
                    else
                    {
                        _logger.LogWarning($"Unknown data type: {data}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error while processing message. Message data: {e.FirstData}");
            }
        }