using GpsCardGatewayPosition.Model.Config; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TelpoDataService.Util; using TelpoDataService.Util.Entities.GpsCard; using TelpoDataService.Util.QueryObjects; using TelpoDataService.Util.Models; using TelpoDataService.Util.Clients; using GpsCardGatewayPosition.Model.Cache; namespace GpsCardGatewayPosition.Service.Cache { public class DeviceCacheManager { private const string CACHE_KEY_DEVICE = "Device_"; private const string CACHE_KEY_DEVICESTATUS = "DeviceStatus_"; private const string CACHE_HASH_KEY_POSITIONSTATUS = "#DevicePositionHash"; private const string CACHE_HASH_KEY_GPSDEVICEPERSON = "#GPSDEVICE_PERSON_HASH"; private const string CACHE_HASH_DEVICESTATUS = "#DEVICE_STATUS_HASH"; private const string CACHE_KEY_GPSDEVICE_WATCH_CONFIG = "#GPSDEVICE_WATCH_CONFIG_HASH"; private readonly ServiceConfig _configService; private readonly GpsCardAccessorClient _deviceApiClient; private readonly GpsCardAccessorClient _deviceStatusApiClient; private readonly ILogger _logger; private int DefaultDurationSeconds { get; } public DeviceCacheManager(IOptions optConfigService, IOptions optConfigAppsettings, GpsCardAccessorClient deviceApiClient, GpsCardAccessorClient deviceStatusApiClient, ILogger logger) { _configService = optConfigService.Value; _deviceApiClient = deviceApiClient; _deviceStatusApiClient = deviceStatusApiClient; _logger = logger; DefaultDurationSeconds = optConfigAppsettings.Value.DefaultDurationSeconds; } public async Task GetDeviceBySerialNoAsync(string messageId, string sn) { string key = CACHE_KEY_DEVICE + sn; var device = await RedisHelper.GetAsync(key).ConfigureAwait(false); if (device == null) { try { string url = _configService.TelpoDataUrl; var param = new GeneralParam { Filters = new List { new QueryFilterCondition { Key=nameof(GpsDevice.Serialno), Value=sn, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal } } }; device = await _deviceApiClient.GetFirstAsync(param, new RequestHeader { RequestId = messageId }).ConfigureAwait(false); if (device != null) { await RedisHelper.SetAsync(key, device, DefaultDurationSeconds); } } catch (Exception ex) { _logger.LogError($"获取查询设备并更新缓存发生异常:{ex.Message}, {ex.StackTrace}"); } } if (device != null && device.Serialno != sn) { _logger.LogError($"缓存不匹配(serialno), src: {sn}, dst: {device.Serialno}"); } return device; } public async Task GetDeviceStatusBySerialNoAsync(string messageId, string sn) { string key = CACHE_KEY_DEVICESTATUS + sn; var deviceStatus = await RedisHelper.GetAsync(key).ConfigureAwait(false); if (deviceStatus == null) { try { var url = _configService.TelpoDataUrl; var param = new GeneralParam { Filters = new List { new QueryFilterCondition { Key=nameof(GpsDeviceStatus.Serialno), Value=sn, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal } } }; deviceStatus = await _deviceStatusApiClient.GetFirstAsync(param, new RequestHeader { RequestId = messageId }).ConfigureAwait(false); if (deviceStatus != null) { RedisHelper.SetAsync(key, deviceStatus, DefaultDurationSeconds); } } catch (Exception ex) { _logger.LogError($"获取设备状态缓存发生异常:{ex.Message}, {ex.StackTrace}"); } } return deviceStatus; } public async Task GetPositionStatusCacheAsync(string sn) { if (string.IsNullOrWhiteSpace(sn)) return null; var status = await RedisHelper.HGetAsync(CACHE_HASH_KEY_POSITIONSTATUS, sn); return status; } public void SetPositionStatusCache(string sn, DevicePositionStatus status) { if (string.IsNullOrWhiteSpace(sn) || status == null) return; RedisHelper.HSetAsync(CACHE_HASH_KEY_POSITIONSTATUS, sn, status); } public void SetDevice(GpsDevice device) { if (device == null) return; string key = CACHE_KEY_DEVICE + device.Serialno; RedisHelper.SetAsync(key, device, DefaultDurationSeconds); } public void SetDeviceStatus(GpsDeviceStatus deviceStatus) { if (deviceStatus == null) return; string key = CACHE_KEY_DEVICESTATUS + deviceStatus.Serialno; RedisHelper.SetAsync(key, deviceStatus, DefaultDurationSeconds); } /// /// 储存rssi 0或1 时的状态值 /// /// public async Task SetStatusHashAsync(GpsDeviceStatus deviceStatus) { if (deviceStatus == null) return; string key = CACHE_KEY_DEVICESTATUS + deviceStatus.Serialno; await RedisHelper.SetAsync(key, deviceStatus, DefaultDurationSeconds); } public async Task GetDeviceKeyBySerialNoAsync(string sn) { try { var hashKey = $"Telpol:HealthyDeviceKey:{sn}"; var value = await RedisHelperDb0.HGetAsync(hashKey, "data").ConfigureAwait(false); _logger.LogInformation($"{sn} 读取 Redis {hashKey}--{value}"); return value ?? string.Empty; } catch (Exception ex) { _logger.LogError($"Redis发生异常:{ex.Message}, {ex.StackTrace}"); return string.Empty; } } public async Task GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(string sn) { if (string.IsNullOrWhiteSpace(sn)) return null; try { var config = await RedisHelperDb7.HGetAsync(CACHE_KEY_GPSDEVICE_WATCH_CONFIG, $"{sn}_0017").ConfigureAwait(false); return (JObject)JsonConvert.DeserializeObject(config); } catch (Exception ex) { _logger.LogWarning($"Redis DB7发生异常:{ex.Message}, {ex.StackTrace}"); } return null; } } }