IOTCloudService.cs 10.4 KB
using HHECS.BllModel;
using HHECS.DAQShared.Dto;
using HHECS.DAQShared.Models;
using HHECS.DAQWebClient.Model;
using HHECS.DAQWebClient.Models;
using System.IO.Compression;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

namespace HHECS.DAQWebClient.Services
{
    public class IOTCloudService
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly CommonService _commonService;
        private readonly IFreeSql _freeSql;
        private readonly JsonSerializerOptions jsonSerializeOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            PropertyNameCaseInsensitive = true
        };

        private readonly JsonSerializerOptions jsonDeserializeOptions = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        };

        public IOTCloudService(IHttpClientFactory httpClientFactory, CommonService commonService, IFreeSql freeSql)
        {
            _httpClientFactory = httpClientFactory;
            _commonService = commonService;
            _freeSql = freeSql;
        }

        private HttpClient InitialHttpClient()
        {
            var client = _httpClientFactory.CreateClient();
            var clientId = _freeSql.Queryable<LocalConfig>().Where(x => x.Code == ConfigType.ClientId.ToString()).First(x => x.Value);
            var urlConfig = string.Empty;
            if (_commonService.IsProductionEnvironment)
            {
                urlConfig = _freeSql.Queryable<LocalConfig>().Where(x => x.Code == ConfigType.IOTCloundAPI.ToString()).First(x => x.Value);
            }
            else
            {
                urlConfig = _freeSql.Queryable<LocalConfig>().Where(x => x.Code == ConfigType.IOTCloundDevelopmentAPI.ToString()).First(x => x.Value);
            }
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("User-Agent", "HHECS.DAQClient");
            client.DefaultRequestHeaders.Add("ClientId", clientId);
            client.BaseAddress = new Uri(urlConfig);
            return client;
        }

        /// <summary>
        /// 推送设备实时数据
        /// </summary>
        /// <param name="equipmentDataQueues"></param>
        public async Task<BllResult> SendEquipmentDataAsync(IEnumerable<EquipmentDataQueue> equipmentDataQueues)
        {
            try
            {
                using var client = InitialHttpClient();
                var data = equipmentDataQueues.Select(x => new EquipmentDataDto
                {
                    Plmeid = x.Id == Guid.Empty ? Guid.NewGuid() : x.Id,
                    EquipmentSN = x.EquipmentCode,
                    Reported = JsonSerializer.Deserialize<List<TagItemDto>>(x.Reported)!,
                    Version = x.Version,
                    Timestamp = x.SourceTimestamp,
                }).ToList();

                var json = JsonSerializer.Serialize(data, jsonSerializeOptions);
                var compressedData = CompressString(json);
                var content = new ByteArrayContent(compressedData);
                // 设置请求头,指明内容是GZip压缩的
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                if (!content.Headers.ContentEncoding.Contains("gzip"))
                {
                    content.Headers.ContentEncoding.Add("gzip");
                }
                var result = await client.PostAsync("Api/Equipment/SendEquipmentData", content);
                var resultContent = await result.Content.ReadAsStringAsync();
                if (result.IsSuccessStatusCode)
                {
                    return JsonSerializer.Deserialize<BllResult>(resultContent, jsonDeserializeOptions)!;
                }

                if (string.IsNullOrEmpty(resultContent))
                {
                    resultContent = result.ReasonPhrase;
                }
                return BllResultFactory.Error($"推送失败:{resultContent}");
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error(ex.Message);
            }
        }

        /// <summary>
        /// 推送某一时间段的数据
        /// </summary>
        /// <param name="equipmentDataQueues"></param>
        /// <returns></returns>
        public async Task<BllResult> SendEquipmentDataV2Async(IEnumerable<EquipmentDataQueue> equipmentDataQueues)
        {
            try
            {
                using var client = InitialHttpClient();
                var data = equipmentDataQueues.Select(x => new EquipmentDataV2Dto
                {
                    Plmeid = x.Id,
                    EquipmentSN = x.EquipmentCode,
                    Reported = JsonSerializer.Deserialize<List<TagItemDto>>(x.Reported)!,
                    Version = x.Version,
                    TimestampStart = x.SourceTimestamp,
                    TimestampEnd = (long)(x.SourceTimestamp + (x.Updated!.Value - x.Created!.Value).TotalMilliseconds),
                });
                var json = JsonSerializer.Serialize(data, jsonSerializeOptions);
                var compressedData = CompressString(json);
                var content = new ByteArrayContent(compressedData);
                // 设置请求头,指明内容是GZip压缩的
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                if (!content.Headers.ContentEncoding.Contains("gzip"))
                {
                    content.Headers.ContentEncoding.Add("gzip");
                }
                var result = await client.PostAsync("Api/Equipment/SendEquipmentDataV2", content);
                var resultContent = await result.Content.ReadAsStringAsync();
                if (result.IsSuccessStatusCode)
                {
                    return JsonSerializer.Deserialize<BllResult>(resultContent, jsonDeserializeOptions)!;
                }

                if (string.IsNullOrEmpty(resultContent))
                {
                    resultContent = result.ReasonPhrase;
                }
                return BllResultFactory.Error($"推送失败:{resultContent}");
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error(ex.Message);
            }
        }

        public async Task<BllResult> UpdateClientStatusAsync(Guid clientId)
        {
            try
            {
                using var client = InitialHttpClient();
                var data = new
                {
                    ClientId = clientId,
                };
                var json = JsonSerializer.Serialize(data, jsonSerializeOptions);
                var compressedData = CompressString(json);
                var temp = DecompressString(compressedData);
                var content = new ByteArrayContent(compressedData);
                // 设置请求头,指明内容是GZip压缩的
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                if (!content.Headers.ContentEncoding.Contains("gzip"))
                {
                    content.Headers.ContentEncoding.Add("gzip");
                }
                var result = await client.PostAsync("Api/Equipment/UpdateClientStatus", content);
                var resultContent = await result.Content.ReadAsStringAsync();
                if (result.IsSuccessStatusCode)
                {
                    return JsonSerializer.Deserialize<BllResult>(resultContent, jsonDeserializeOptions)!;
                }

                if (string.IsNullOrEmpty(resultContent))
                {
                    resultContent = result.ReasonPhrase;
                }
                return BllResultFactory.Error($"推送失败:{resultContent}");
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error(ex.Message);
            }
        }

        /// <summary>
        /// 获取基础配置数据
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public async Task<BllResult<List<EquipmentType>>> GetClientEquipmentDataAsync(Guid clientId)
        {
            try
            {
                using var client = InitialHttpClient();
                if (!client.DefaultRequestHeaders.AcceptEncoding.Any(encoding => encoding.Value == "gzip"))
                {
                    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                }
                var result = await client.GetAsync($"Api/Equipment/GetClientEquipmentData?clientId={clientId}");
                var resultContentBytes = await result.Content.ReadAsByteArrayAsync();
                var resultContent = DecompressString(resultContentBytes);
                if (result.IsSuccessStatusCode)
                {
                    return JsonSerializer.Deserialize<BllResult<List<EquipmentType>>>(resultContent, jsonDeserializeOptions)!;
                }

                if (string.IsNullOrEmpty(resultContent))
                {
                    resultContent = result.ReasonPhrase;
                }
                return BllResultFactory.Error<List<EquipmentType>>(resultContent!);
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error<List<EquipmentType>>(ex.Message);
            }
        }

        /// <summary>
        /// 数据压缩
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private static byte[] CompressString(string text)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(text);
            using var memoryStream = new MemoryStream();
            using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
            {
                gZipStream.Write(buffer, 0, buffer.Length);
            }
            return memoryStream.ToArray();
        }

        /// <summary>
        /// 数据解压缩
        /// </summary>
        /// <param name="gzip"></param>
        /// <returns></returns>
        private static string DecompressString(byte[] gzip)
        {
            using var memoryStream = new MemoryStream(gzip);
            using var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress);
            using var streamReader = new StreamReader(gZipStream, Encoding.UTF8);
            return streamReader.ReadToEnd();
        }
    }
}