Esempio n. 1
0
        protected virtual SendResult SaveRequestResults(Stream responseStream, TransportSendStats sendStats)
        {
            bool needRetry = false;
            TransportResponseStats responseStats;

            using (var streamReader = new StreamReader(responseStream))
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    var jsonSerializer = new JsonSerializer();
                    // сохраним потоки данных конфигураций при десериализации
                    jsonSerializer
                    .Converters
                    .Add(new ConfigurationsByteArraysToFilesConverter(this.configurationStore));

                    var response = jsonSerializer.Deserialize <TransportResponse>(jsonReader);

                    this.sendStateStore.ConfigurationsUpdated();

                    // изменеилась статическая конфигурация
                    if (response.StaticConfigData != null)
                    {
                        this.agentInfoService.SetStaticConfig(new TransportStaticConfig
                        {
                            ConfigToken   = response.StaticConfigData.ConfigToken,
                            ConfigVersion = response.StaticConfigData.ConfigVersion,
                        });

                        return(SendResult.Retry(TransportConstants.DefaultUpdateStaticConfigTimeout));
                    }
                    else
                    {
                        // изменилась бд системы (например сменили сервера)
                        if (response.DbTokenData != null)
                        {
                            this.agentInfoService.SetDbToken(new TransportDbTokenData
                            {
                                DbToken = response.DbTokenData.DbToken
                            });

                            this.packetManager.RemoveAll();

                            //return SendResult.Retry(TransportConstants.DefaultUpdateDbTokenTimeout);
                        }

                        responseStats = new TransportResponseStats()
                        {
                            SendedPacketsStats = sendStats.SendedPacketsStats,
                            // изменилась бд системы
                            TransferedPacketsProcessingResults = response.DbTokenData != null ? new List <TransferedPacketStats>() : sendStats.SendedPacketsStats.Select(x =>
                            {
                                return(new TransferedPacketStats
                                {
                                    PacketInfo = x.Key,
                                    SendStats = x.Value,
                                    Result = response.TransferedPackets.First(p => p.PacketId == x.Key.Id && p.ProviderKey == x.Key.ProviderKey).Result,
                                });
                            }).ToList(),
                        };
                    }
                }

            var packets = responseStats.TransferedPacketsProcessingResults.ToList();

            foreach (var item in packets)
            {
                var packet = item.PacketInfo;
                if (item.Result == PacketProcessingResult.Saved)
                {
                    this.packetManager.SaveSendStats(packet.ProviderKey, packet.Id, item.SendStats);
                }
                else if (item.Result == PacketProcessingResult.Error)
                {
                    needRetry = true;
                }
                else if (item.Result == PacketProcessingResult.Resend)
                {
                    // сбрасываем статистику
                    this.packetManager.SaveSendStats(packet.ProviderKey, packet.Id, new SendStats());
                }
                // игнорим эти результаты (если потом появится обработчик на сервере или обновиться агент до нормальной версии и в нём будет другая обработка, предполагаю что следующий набор данных будет доставлен успешно)
                //else if (item.Result == PacketProcessingResult.Unknown)
                //{
                //}
                //else if (item.Result == PacketProcessingResult.NoProcessor)
                //{
                //}
                else
                {
                    this.packetManager.SaveSendStats(packet.ProviderKey, packet.Id, item.SendStats);
                }
            }

            //var configurations = stats.Configurations.ToList();
            //foreach (var item in configurations)
            //{
            //}

            return(needRetry
                ? SendResult.Retry(settings.ErrorRetryTimeout)
                : SendResult.Success());
        }
Esempio n. 2
0
        protected virtual SendResult SendIteration(IList <ITransportPacketInfo> packetInfos, IList <ConfigurationRequestDataItem> configurationsToDownloadInfos, SendIterationContext context)
        {
            var url = this.GetUri(this.GetSendMessageHeaders(context));

            string formDataBoundary = string.Format("----------{0:N}", Guid.NewGuid());
            string contentType      = "multipart/form-data; boundary=" + formDataBoundary;

#if !NETSTANDARD2_0
            try
            {
                var req = WebRequest.Create(url) as HttpWebRequest;
                //req.KeepAlive = true;
                //req.KeepAlive = false;
                req.AllowWriteStreamBuffering = false;
                req.Method      = "POST";
                req.ContentType = contentType;

                TransportSendStats sendededStats = null;
                using (Stream requestStream = req.GetRequestStream())
                {
                    sendededStats = this.WriteMessageToBody(formDataBoundary, requestStream, packetInfos, configurationsToDownloadInfos, context);
                }

                try
                {
                    var response = req.GetResponse();
                    using (var resStream = response.GetResponseStream())
                        using (var streamReader = new StreamReader(resStream))
                        {
                            // обрабатывает ответ
                            return(this.SaveRequestResults(resStream, sendededStats));
                        }
                }
                catch (WebException ex)
                {
                    var wRespStatusCode = ((HttpWebResponse)ex.Response).StatusCode;
                    if ((int)wRespStatusCode == 429)
                    {
                        var timeout = int.TryParse(ex.Response.Headers.GetValues("Retry-After").FirstOrDefault(), out var retryTm)
                            ? retryTm
                            : Convert.ToInt64(settings.ErrorRetryTimeout.TotalMilliseconds);

                        return(SendResult.Retry(timeout));
                    }

                    // при общих ошибках
                    return(SendResult.Retry(settings.ServerErrorRetryTimeout));
                }
            }
            catch (Exception)
            {
                // при общих ошибках
                return(SendResult.Retry(settings.ErrorRetryTimeout));
            }
#else
            try
            {
                TransportSendStats sendededStats = null;
                var reqContent = new HttpRequestMessage(HttpMethod.Post, url)
                {
                    Content = new WriteToStreamContent((requestStream, ctx) =>
                    {
                        sendededStats = this.WriteMessageToBody(formDataBoundary, requestStream, packetInfos, configurationsToDownloadInfos, context);
                    }),
                };

                // workaround for net core 2.2 and analogs
                // нужно для того чтобы в случаях "отказов" не происходило чтение всего тела запроса, а читались только основные параметры
                reqContent.Headers.ExpectContinue      = true;
                reqContent.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
                var result = this.httpClient.SendAsync(reqContent, HttpCompletionOption.ResponseContentRead).Result;

                if (result.IsSuccessStatusCode)
                {
                    using (var stream = result.Content.ReadAsStreamAsync().Result)
                    {
                        // обрабатывает ответ
                        return(this.SaveRequestResults(stream, sendededStats));
                    };
                }
                else
                {
                    if ((int)result.StatusCode == 429)
                    {
                        var timeout = int.TryParse(result.Headers.GetValues("Retry-After").FirstOrDefault(), out var retryTm)
                                        ? retryTm
                                        : Convert.ToInt64(settings.ErrorRetryTimeout.TotalMilliseconds);

                        return(SendResult.Retry(timeout));
                    }

                    return(SendResult.Retry(settings.ServerErrorRetryTimeout));
                }
            }
            catch (Exception)
            {
                // при общих ошибках
                return(SendResult.Retry(settings.ErrorRetryTimeout));
            }
#endif
        }