ConnectService.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using JsonRpcLite.Services;
  6. using WingInterfaceLibrary.DB.Request;
  7. using WingInterfaceLibrary.DTO.Device;
  8. using WingInterfaceLibrary.DTO.Organization;
  9. using WingInterfaceLibrary.Enum;
  10. using WingInterfaceLibrary.Interface;
  11. using WingInterfaceLibrary.Request;
  12. using WingInterfaceLibrary.Request.Authentication;
  13. using WingInterfaceLibrary.Request.Device;
  14. using WingInterfaceLibrary.Result.Device;
  15. using WingServerCommon.Log;
  16. using WingServerCommon.Mapper;
  17. using WingServerCommon.Service;
  18. using WingServerCommon.Config;
  19. using WingServerCommon.Config.Parameters;
  20. namespace WingDeviceService.Service
  21. {
  22. /// <summary>
  23. /// 鉴权服务
  24. /// </summary>
  25. public partial class DeviceService : JsonRpcService, IConnectService
  26. {
  27. private readonly bool _isMergedChannel = ConfigurationManager.GetParammeter<BoolParameter>("Device", "IsMergedChannel").Value;
  28. private readonly int _highMergedVideoOutputWidth = ConfigurationManager.GetParammeter<IntParameter>("Device", "HighMergedVideoOutputWidth").Value;
  29. private readonly int _highMergedVideoOutputHeight = ConfigurationManager.GetParammeter<IntParameter>("Device", "HighMergedVideoOutputHeight").Value;
  30. private readonly int _lowMergedVideoOutputWidth = ConfigurationManager.GetParammeter<IntParameter>("Device", "LowMergedVideoOutputWidth").Value;
  31. private readonly int _lowMergedVideoOutputHeight = ConfigurationManager.GetParammeter<IntParameter>("Device", "LowMergedVideoOutputHeight").Value;
  32. private readonly string _highCpuLevels = ConfigurationManager.GetParammeter<StringParameter>("Device", "HighCpuLevels").Value;
  33. private readonly string _sourceUrl = "cloud.xinglinghui.com";
  34. private readonly object _createShortCodeLocker = new object();
  35. /// <summary>设备连接云服务</summary>
  36. /// <param name="request">请求对象</param>
  37. /// <returns>授权响应</returns>
  38. /// <remarks>POST</remarks>
  39. public async Task<ConnectResult> ConnectAsync(ConnectRequest request)
  40. {
  41. try
  42. {
  43. #region Params Check
  44. if (string.IsNullOrWhiteSpace(request.DeviceUniqueCode))
  45. {
  46. ThrowCustomerException(CustomerRpcCode.DeviceUniqueCodeEmpty, "DeviceUniqueCode empty error");
  47. }
  48. if (string.IsNullOrWhiteSpace(request.DeviceModel))
  49. {
  50. ThrowCustomerException(CustomerRpcCode.DeviceModelEmpty, "DeviceModel empty error");
  51. }
  52. if (string.IsNullOrWhiteSpace(request.DeviceType))
  53. {
  54. ThrowCustomerException(CustomerRpcCode.DeviceTypeEmpty, "DeviceType empty error");
  55. }
  56. if (string.IsNullOrWhiteSpace(request.SoftwareVersion))
  57. {
  58. ThrowCustomerException(CustomerRpcCode.SoftwareVersionEmpty, "SoftwareVersion empty error");
  59. }
  60. if (string.IsNullOrWhiteSpace(request.SystemVersion))
  61. {
  62. ThrowCustomerException(CustomerRpcCode.SystemVersionEmpty, "SystemVersion empty error");
  63. }
  64. if (string.IsNullOrWhiteSpace(request.CPUModel))
  65. {
  66. ThrowCustomerException(CustomerRpcCode.CPUModelEmpty, "CPUModel empty error");
  67. }
  68. if (string.IsNullOrWhiteSpace(request.SystemLanguage))
  69. {
  70. ThrowCustomerException(CustomerRpcCode.SystemVersionEmpty, "SystemLanguage empty error");
  71. }
  72. var deviceTypeList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceType });
  73. if (!deviceTypeList.Select(x => x.DictionaryCode).Contains(request.DeviceType))
  74. {
  75. ThrowCustomerException(CustomerRpcCode.DeviceTypeError, "DeviceType error");
  76. }
  77. var deviceModelList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceModel });
  78. if (!deviceModelList.Select(x => x.Value).Contains(request.DeviceModel))
  79. {
  80. //ThrowCustomerException(CustomerRpcCode.DeviceModelError, "DeviceModel error");
  81. Logger.WriteLineWarn(CustomerRpcCode.DeviceModelError.ToString()+"_"+request.DeviceModel);
  82. }
  83. #endregion
  84. var deviceDto = await _deviceInfoDBServiceProxy.FindDeviceInfoBySerialNumberAsync(request.DeviceUniqueCode);
  85. if (deviceDto == null)
  86. {
  87. deviceDto = new DeviceInfoDTO()
  88. {
  89. SerialNumber = request.DeviceUniqueCode,
  90. Name = request.Name,
  91. Password = request.Password,
  92. Description = request.Description,
  93. OrganizationCode = request.OrganizationCode,
  94. DeviceModel = request.DeviceModel,
  95. DeviceType = request.DeviceType,
  96. DeviceSoftwareVersion = request.SoftwareVersion,
  97. SystemVersion = request.SystemVersion,
  98. CPUModel = request.CPUModel,
  99. SystemLanguage = request.SystemLanguage,
  100. IsEncryptedShow = true,
  101. MergedChannel = _isMergedChannel
  102. };
  103. SetDeviceMergedOutput(request.DeviceModel, request.CPUModel, deviceDto);
  104. var shortCode = deviceDto.ShortCode;
  105. for (var i = 0; i < 5; i++)
  106. {
  107. shortCode = GenerateShortCode();
  108. if (!string.IsNullOrWhiteSpace(shortCode))
  109. {
  110. var device = await _deviceInfoDBServiceProxy.FindDeviceInfoByShortCodeAsync(shortCode);
  111. if (device == null || string.IsNullOrWhiteSpace(device.DeviceCode))
  112. {
  113. break;
  114. }
  115. }
  116. shortCode = string.Empty;
  117. }
  118. deviceDto.ShortCode = shortCode;
  119. deviceDto.DeviceCode = await _deviceInfoDBServiceProxy.InsertDeviceInfoAsync(new WingInterfaceLibrary.DB.Request.CreateDeviceInfoDBRequest
  120. {
  121. Data = deviceDto
  122. });
  123. //创建虚拟机构
  124. var inventedOrgCode = "invented_" + shortCode;
  125. var orgData = new TableDataItem<OrganizationDTO>
  126. {
  127. Data = new OrganizationDTO
  128. {
  129. OrganizationCode = inventedOrgCode,
  130. RootCode = inventedOrgCode,
  131. OrganizationName = shortCode,
  132. OrganizationType = OrganizationTypeEnum.Corporation,
  133. State = OrganizationStateEnum.Audited,
  134. RegionCode = "1000000",
  135. Isinvented = true
  136. },
  137. PlatformDatas = new Dictionary<string, string>(),
  138. ExtensionData = string.Empty,
  139. };
  140. await _organizationDBService.CreateOrganizationsAsync(new CreateOrganizationsDBRequest { Infos = new List<TableDataItem<OrganizationDTO>> { orgData } });
  141. }
  142. else
  143. {
  144. deviceDto.DeviceModel = request.DeviceModel;
  145. deviceDto.DeviceType = request.DeviceType;
  146. deviceDto.DeviceSoftwareVersion = request.SoftwareVersion;
  147. deviceDto.SystemVersion = request.SystemVersion;
  148. deviceDto.CPUModel = request.CPUModel;
  149. SetDeviceMergedOutput(request.DeviceModel, request.CPUModel, deviceDto);
  150. // deviceDto.Description = request.Description;
  151. // deviceDto.Name = request.Name;
  152. // deviceDto.OrganizationCode = request.OrganizationCode;
  153. deviceDto.SystemLanguage = request.SystemLanguage;
  154. await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDto.DeviceCode, deviceDto, string.Empty, true);
  155. }
  156. var deviceName = deviceDto.Name;
  157. if (string.IsNullOrWhiteSpace(deviceName))
  158. {
  159. deviceName = deviceDto.ShortCode;
  160. }
  161. var applyRequest = new ApplyTokenRequest(AccountType.US, deviceName, request.Platform, request.LoginSource, deviceDto.DeviceCode, ConfigurationManager.Host, 0, request.InstallVersion);
  162. var tokenInfo = await _authenticationService.ApplyTokenAsync(applyRequest);
  163. if (!string.IsNullOrWhiteSpace(tokenInfo.Code))
  164. {
  165. _deviceHeartRateManager.AddOrUpdate(tokenInfo.Code);
  166. }
  167. return new ConnectResult
  168. {
  169. Token = tokenInfo.Code,
  170. UniqueCode = deviceDto.ShortCode
  171. };
  172. }
  173. catch (Exception ex)
  174. {
  175. Logger.WriteLineWarn($"device connect server failed, err:{ex}");
  176. throw;
  177. }
  178. }
  179. private void SetDeviceMergedOutput(string deviceModel, string cpuModel, DeviceInfoDTO deviceDto)
  180. {
  181. var highCpu = _highCpuLevels?.Split(',');
  182. if(deviceModel.ToUpper().StartsWith("SP002"))
  183. {
  184. deviceDto.MergedVideoOutputWidth = _highMergedVideoOutputWidth;
  185. deviceDto.MergedVideoOutputHeight = _highMergedVideoOutputHeight;
  186. }
  187. else if(highCpu!=null && highCpu.Contains(cpuModel))
  188. {
  189. deviceDto.MergedVideoOutputWidth = _highMergedVideoOutputWidth;
  190. deviceDto.MergedVideoOutputHeight = _highMergedVideoOutputHeight;
  191. }
  192. else if(cpuModel.StartsWith("I"))
  193. {
  194. int.TryParse(cpuModel.Substring(1,cpuModel.IndexOf('-')-1),out int cpuLevel);
  195. if(cpuLevel>5)
  196. {
  197. deviceDto.MergedVideoOutputWidth = _highMergedVideoOutputWidth;
  198. deviceDto.MergedVideoOutputHeight = _highMergedVideoOutputHeight;
  199. }
  200. else
  201. {
  202. deviceDto.MergedVideoOutputWidth = _lowMergedVideoOutputWidth;
  203. deviceDto.MergedVideoOutputHeight = _lowMergedVideoOutputHeight;
  204. }
  205. }
  206. else
  207. {
  208. deviceDto.MergedVideoOutputWidth = _lowMergedVideoOutputWidth;
  209. deviceDto.MergedVideoOutputHeight = _lowMergedVideoOutputHeight;
  210. }
  211. }
  212. /// <summary>查询当前设备信息</summary>
  213. /// <param name="request">请求对象</param>
  214. /// <returns>设备信息</returns>
  215. /// <remarks>POST</remarks>
  216. public async Task<CacheDeviceDTO> GetDeviceByTokenAsync(TokenRequest request)
  217. {
  218. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  219. var deviceDTO = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  220. var cacheDeviceInfo = deviceDTO.MappingTo<CacheDeviceDTO>();
  221. cacheDeviceInfo.IsOnline = await GetDeviceOnlineState(deviceCode);
  222. return cacheDeviceInfo;
  223. }
  224. /// <summary>设备与云服务断开连接</summary>
  225. /// <param name="request">请求对象</param>
  226. /// <returns>是否成功</returns>
  227. /// <value>true</value>
  228. public async Task<bool> DisConnectAsync(TokenRequest request)
  229. {
  230. try
  231. {
  232. await _authenticationService.LogOffAsync(request);
  233. return true;
  234. }
  235. catch (Exception ex)
  236. {
  237. Logger.WriteLineWarn($"device disconnect failed, ex:{ex}");
  238. throw;
  239. }
  240. }
  241. /// <summary>获取设备在线状态</summary>
  242. /// <param name="deviceCode"></param>
  243. /// <returns></returns>
  244. private async Task<bool> GetDeviceOnlineState(string deviceCode)
  245. {
  246. var tokenList = await _authenticationService.GetTokensWithClientIdAsync(new GetTokensWithClientIdRequest { ClientId = deviceCode });
  247. return tokenList.FirstOrDefault()?.IsOnline ?? false;
  248. }
  249. /// <summary>生成唯一 shortCode</summary>
  250. /// <returns></returns>
  251. private string GenerateShortCode()
  252. {
  253. try
  254. {
  255. lock (_createShortCodeLocker)
  256. {
  257. var uniqueId = new byte[6];
  258. var rand = new Random((int)(DateTime.Now.Ticks % 1000000));
  259. for (int i = 0; i < 6; i++)
  260. {
  261. int randCode;
  262. do
  263. {
  264. randCode = rand.Next(50, 90);
  265. uniqueId[i] = Convert.ToByte(randCode);
  266. } while (randCode >= 58 && randCode <= 64 || randCode == 79 || randCode == 73);
  267. }
  268. return System.Text.Encoding.ASCII.GetString(uniqueId);
  269. }
  270. }
  271. catch (Exception ex)
  272. {
  273. Logger.WriteLineError($"GenerateShortCode error {ex}");
  274. }
  275. return string.Empty;
  276. }
  277. /// <summary>
  278. /// 设置敏感信息是否加密请求
  279. /// </summary>
  280. /// <param name="request">设置敏感信息是否加密请求实体</param>
  281. /// <returns>是否成功</returns>
  282. public async Task<bool> SetDeviceIsEncryptedShowAsync(SetDeviceIsEncryptedShowRequest request)
  283. {
  284. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  285. var deviceDTO = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  286. if (deviceDTO == null)
  287. {
  288. ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
  289. }
  290. deviceDTO.IsEncryptedShow = request.IsEncryptedShow;
  291. return await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDTO.DeviceCode, deviceDTO, string.Empty);
  292. }
  293. }
  294. }