using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using JsonRpcLite.Services; using WingInterfaceLibrary.DB.Request; using WingInterfaceLibrary.DTO.Device; using WingInterfaceLibrary.DTO.Organization; using WingInterfaceLibrary.Enum; using WingInterfaceLibrary.Interface; using WingInterfaceLibrary.Request; using WingInterfaceLibrary.Request.Authentication; using WingInterfaceLibrary.Request.Device; using WingInterfaceLibrary.Result.Device; using WingServerCommon.Log; using WingServerCommon.Mapper; using WingServerCommon.Service; using WingServerCommon.Config; namespace WingDeviceService.Service { /// /// 鉴权服务 /// public partial class DeviceService : JsonRpcService, IConnectService { private readonly string _sourceUrl = "cloud.xinglinghui.com"; private readonly object _createShortCodeLocker = new object(); /// 设备连接云服务 /// 请求对象 /// 授权响应 /// POST public async Task ConnectAsync(ConnectRequest request) { try { #region Params Check if (string.IsNullOrWhiteSpace(request.DeviceUniqueCode)) { ThrowCustomerException(CustomerRpcCode.DeviceUniqueCodeEmpty, "DeviceUniqueCode empty error"); } if (string.IsNullOrWhiteSpace(request.DeviceModel)) { ThrowCustomerException(CustomerRpcCode.DeviceModelEmpty, "DeviceModel empty error"); } if (string.IsNullOrWhiteSpace(request.DeviceType)) { ThrowCustomerException(CustomerRpcCode.DeviceTypeEmpty, "DeviceType empty error"); } if (string.IsNullOrWhiteSpace(request.SoftwareVersion)) { ThrowCustomerException(CustomerRpcCode.SoftwareVersionEmpty, "SoftwareVersion empty error"); } if (string.IsNullOrWhiteSpace(request.SystemVersion)) { ThrowCustomerException(CustomerRpcCode.SystemVersionEmpty, "SystemVersion empty error"); } if (string.IsNullOrWhiteSpace(request.CPUModel)) { ThrowCustomerException(CustomerRpcCode.CPUModelEmpty, "CPUModel empty error"); } if (string.IsNullOrWhiteSpace(request.SystemLanguage)) { ThrowCustomerException(CustomerRpcCode.SystemVersionEmpty, "SystemLanguage empty error"); } var deviceTypeList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceType }); if (!deviceTypeList.Select(x => x.DictionaryCode).Contains(request.DeviceType)) { ThrowCustomerException(CustomerRpcCode.DeviceTypeError, "DeviceType error"); } var deviceModelList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceModel }); if (!deviceModelList.Select(x => x.Value).Contains(request.DeviceModel)) { //ThrowCustomerException(CustomerRpcCode.DeviceModelError, "DeviceModel error"); Logger.WriteLineWarn(CustomerRpcCode.DeviceModelError.ToString()+"_"+request.DeviceModel); } #endregion var deviceDto = await _deviceInfoDBServiceProxy.FindDeviceInfoBySerialNumberAsync(request.DeviceUniqueCode); if (deviceDto == null) { deviceDto = new DeviceInfoDTO() { SerialNumber = request.DeviceUniqueCode, Name = request.Name, Password = request.Password, Description = request.Description, OrganizationCode = request.OrganizationCode, DeviceModel = request.DeviceModel, DeviceType = request.DeviceType, DeviceSoftwareVersion = request.SoftwareVersion, SystemVersion = request.SystemVersion, CPUModel = request.CPUModel, SystemLanguage = request.SystemLanguage, IsEncryptedShow = true }; var shortCode = deviceDto.ShortCode; for (var i = 0; i < 5; i++) { shortCode = GenerateShortCode(); if (!string.IsNullOrWhiteSpace(shortCode)) { var device = await _deviceInfoDBServiceProxy.FindDeviceInfoByShortCodeAsync(shortCode); if (device == null || string.IsNullOrWhiteSpace(device.DeviceCode)) { break; } } shortCode = string.Empty; } deviceDto.ShortCode = shortCode; deviceDto.DeviceCode = await _deviceInfoDBServiceProxy.InsertDeviceInfoAsync(new WingInterfaceLibrary.DB.Request.CreateDeviceInfoDBRequest { Data = deviceDto }); //创建虚拟机构 var inventedOrgCode = "invented_" + shortCode; var orgData = new TableDataItem { Data = new OrganizationDTO { OrganizationCode = inventedOrgCode, RootCode = inventedOrgCode, OrganizationName = shortCode, OrganizationType = OrganizationTypeEnum.Corporation, State = OrganizationStateEnum.Audited, RegionCode = "1000000", Isinvented = true }, PlatformDatas = new Dictionary(), ExtensionData = string.Empty, }; await _organizationDBService.CreateOrganizationsAsync(new CreateOrganizationsDBRequest { Infos = new List> { orgData } }); } else { deviceDto.DeviceModel = request.DeviceModel; deviceDto.DeviceType = request.DeviceType; deviceDto.DeviceSoftwareVersion = request.SoftwareVersion; deviceDto.SystemVersion = request.SystemVersion; deviceDto.CPUModel = request.CPUModel; // deviceDto.Description = request.Description; // deviceDto.Name = request.Name; // deviceDto.OrganizationCode = request.OrganizationCode; deviceDto.SystemLanguage = request.SystemLanguage; await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDto.DeviceCode, deviceDto, string.Empty, true); } var deviceName = deviceDto.Name; if (string.IsNullOrWhiteSpace(deviceName)) { deviceName = deviceDto.ShortCode; } var applyRequest = new ApplyTokenRequest(AccountType.US, deviceName, request.Platform, request.LoginSource, deviceDto.DeviceCode, ConfigurationManager.Host, 0); var tokenInfo = await _authenticationService.ApplyTokenAsync(applyRequest); if (!string.IsNullOrWhiteSpace(tokenInfo.Code)) { _deviceHeartRateManager.AddOrUpdate(tokenInfo.Code); } return new ConnectResult { Token = tokenInfo.Code, UniqueCode = deviceDto.ShortCode }; } catch (Exception ex) { Logger.WriteLineWarn($"device connect server failed, err:{ex}"); throw; } } /// 查询当前设备信息 /// 请求对象 /// 设备信息 /// POST public async Task GetDeviceByTokenAsync(TokenRequest request) { var deviceCode = await GetClientIdByTokenAsync(request.Token); var deviceDTO = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode); var cacheDeviceInfo = deviceDTO.MappingTo(); cacheDeviceInfo.IsOnline = await GetDeviceOnlineState(deviceCode); return cacheDeviceInfo; } /// 设备与云服务断开连接 /// 请求对象 /// 是否成功 /// true public async Task DisConnectAsync(TokenRequest request) { try { await _authenticationService.LogOffAsync(request); return true; } catch (Exception ex) { Logger.WriteLineWarn($"device disconnect failed, ex:{ex}"); throw; } } /// 获取设备在线状态 /// /// private async Task GetDeviceOnlineState(string deviceCode) { var tokenList = await _authenticationService.GetTokensWithClientIdAsync(new GetTokensWithClientIdRequest { ClientId = deviceCode }); return tokenList.FirstOrDefault()?.IsOnline ?? false; } /// 生成唯一 shortCode /// private string GenerateShortCode() { try { lock (_createShortCodeLocker) { var uniqueId = new byte[6]; var rand = new Random((int)(DateTime.Now.Ticks % 1000000)); for (int i = 0; i < 6; i++) { int randCode; do { randCode = rand.Next(50, 90); uniqueId[i] = Convert.ToByte(randCode); } while (randCode >= 58 && randCode <= 64 || randCode == 79 || randCode == 73); } return System.Text.Encoding.ASCII.GetString(uniqueId); } } catch (Exception ex) { Logger.WriteLineError($"GenerateShortCode error {ex}"); } return string.Empty; } /// /// 设置敏感信息是否加密请求 /// /// 设置敏感信息是否加密请求实体 /// 是否成功 public async Task SetDeviceIsEncryptedShowAsync(SetDeviceIsEncryptedShowRequest request) { var deviceCode = await GetClientIdByTokenAsync(request.Token); var deviceDTO = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode); if (deviceDTO == null) { ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device"); } deviceDTO.IsEncryptedShow = request.IsEncryptedShow; return await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDTO.DeviceCode, deviceDTO, string.Empty); } } }