using System.ComponentModel; using System; using System.Collections.Concurrent; using System.Threading.Tasks; using WingServerCommon.Log; using WingInterfaceLibrary.Interface; using WingInterfaceLibrary.Enum; using System.Collections.Generic; using WingServerCommon.Config; using WingServerCommon.Config.Parameters; namespace WingDeviceService.Common { internal class RemoteConnectManager { private ConcurrentDictionary _remoteConnects = new ConcurrentDictionary(); private ConcurrentDictionary _deviceRemoteConnects = new ConcurrentDictionary(); private Func OnRemoteConnectOnlineState; private Func OnDeviceRemoteConnectOnlineState; private int _rateSeconds => EnvironmentConfigManager.GetParammeter("Device", "RemoteControlHeartRateSeconds").Value; private IAuthenticationService _authenticationService; public RemoteConnectManager(Func setOnlineState, Func deviceSetOnlineState, IAuthenticationService _authService) { _authenticationService = _authService; OnRemoteConnectOnlineState = setOnlineState; OnDeviceRemoteConnectOnlineState = deviceSetOnlineState; StartCheckClients(); } /// /// 加入检测集合 /// /// /// /// /// public void AddOrUpdate(string key, string userToken, string deviceToken, string deviceCode, string userCode, string roomId, ConnectStatusEnum statusEnum, LoginSource loginSource, TransactionTypeEnum transactionType = TransactionTypeEnum.AfterSales) { _remoteConnects.AddOrUpdate(key, new RemoteConnectDTO(userToken, deviceToken, deviceCode, userCode, roomId, statusEnum, transactionType, loginSource), (k, v) => { v.Activate(); v.StatusEnum = statusEnum; v.DeviceToken = deviceToken; v.LoginSource = loginSource; v.UserToken = userToken; v.IsNeedSyn = v.IsNeedSyn; return v; }); } /// /// 加入检测集合 /// /// /// /// /// public void AddOrUpdateHeart(string key, bool isNeedSyn, string userToken, string deviceToken, string deviceCode, string userCode, string roomId, ConnectStatusEnum statusEnum, LoginSource loginSource, TransactionTypeEnum transactionType = TransactionTypeEnum.AfterSales) { _remoteConnects.AddOrUpdate(key, new RemoteConnectDTO(isNeedSyn, userToken, deviceToken, deviceCode, userCode, roomId, statusEnum, transactionType, loginSource), (k, v) => { v.Activate(); v.StatusEnum = statusEnum; v.DeviceToken = deviceToken; v.LoginSource = loginSource; v.UserToken = userToken; v.IsNeedSyn = isNeedSyn; return v; }); } /// /// 加入检测集合 /// /// /// /// /// public void DeviceAddOrUpdate(string key, string deviceToken, string userToken, string userCode, string deviceCode, TransactionTypeEnum transactionType) { _deviceRemoteConnects.AddOrUpdate(key, new DeviceRemoteConnectDTO(deviceToken, userToken, userCode, deviceCode, transactionType), (k, v) => { v.UserToken = userToken; v.DeviceToken = deviceToken; v.IsNeedSyn = v.IsNeedSyn; v.Activate(); return v; }); } /// /// 加入检测集合 /// /// /// /// /// public void DeviceAddOrUpdateHeart(string key, bool isNeedSyn, string deviceToken, string userToken, string userCode, string deviceCode, TransactionTypeEnum transactionType) { _deviceRemoteConnects.AddOrUpdate(key, new DeviceRemoteConnectDTO(isNeedSyn, deviceToken, userToken, userCode, deviceCode, transactionType), (k, v) => { v.UserToken = userToken; v.DeviceToken = deviceToken; v.IsNeedSyn = isNeedSyn; v.Activate(); return v; }); } /// /// 是否存在token /// /// /// public TransactionTypeEnum GetConnectTransactionType(string key) { TransactionTypeEnum transactionType = TransactionTypeEnum.AfterSales; if (_remoteConnects?.Count > 0) { var res = _remoteConnects.ContainsKey(key); if (res) { transactionType = _remoteConnects[key].TransactionType; } } return transactionType; } /// /// 获取 /// /// /// public string GetRoomId(string key) { string result = ""; if (_remoteConnects?.Count > 0) { var res = _remoteConnects.ContainsKey(key); if (res) { result = _remoteConnects[key]?.RoomId ?? string.Empty; } } return result; } /// /// 获取 /// /// /// public bool GetExistDeviceRoomId(string key) { bool res = false; if (_deviceRemoteConnects?.Count > 0) { res = _deviceRemoteConnects.ContainsKey(key); } return res; } /// /// 获取 /// /// /// public RemoteConnectDTO GetRemoteConnectDTO(string key) { RemoteConnectDTO result = null; if (_remoteConnects?.Count > 0) { var res = _remoteConnects.ContainsKey(key); if (res) { result = _remoteConnects[key]; } } return result; } /// /// 获取 /// /// /// public DeviceRemoteConnectDTO GetDeviceRemoteConnectDTO(string key) { DeviceRemoteConnectDTO result = null; if (_deviceRemoteConnects?.Count > 0) { var res = _deviceRemoteConnects.ContainsKey(key); if (res) { result = _deviceRemoteConnects[key]; } } return result; } /// /// 根据用户token查询所有的连接状态 /// /// /// public List GetAllRemoteConnectByUserToken(string userToken) { var result = new List(); if (_remoteConnects?.Count > 0) { foreach (var item in _remoteConnects.Values) { if (item.UserToken == userToken) { result.Add(item); } } } return result; } /// /// 根据deviceCode查询所有的连接状态 /// /// /// public List GetAllRemoteConnectByDeviceToken(string deviceToken) { var result = new List(); if (_deviceRemoteConnects?.Count > 0) { foreach (var item in _deviceRemoteConnects.Values) { if (item.DeviceToken == deviceToken) { result.Add(item); } } } return result; } public IList GetAllRemoteConnectList(string deviceCode) { var dataList = new List(); if (_remoteConnects?.Count > 0) { foreach (var item in _remoteConnects.Values) { if (item.DeviceCode == deviceCode) { dataList.Add(item); } } } return dataList; } public IList GetAllDeviceRemoteConnectList(string deviceCode) { var dataList = new List(); if (_deviceRemoteConnects?.Count > 0) { foreach (var item in _deviceRemoteConnects.Values) { if (item.DeviceCode == deviceCode) { dataList.Add(item); } } } return dataList; } public RemoteConnectDTO GetDeviceRemoteConnectInfo(string deviceCode) { RemoteConnectDTO info = null; if (_remoteConnects?.Count > 0) { foreach (var item in _remoteConnects.Values) { if (item.DeviceCode == deviceCode) { info = item; break; } } } return info; } /// /// 查询设备是否空闲 /// /// /// /// 是否被他人专用 public int IsIdle(string userToken, string deviceCode, TransactionTypeEnum type = TransactionTypeEnum.AfterSales) { int res = 0; if (_remoteConnects?.Count > 0) { RemoteConnectDTO checkItem = null; foreach (var item in _remoteConnects.Values) { if (item.DeviceCode == deviceCode) { checkItem = item; break; } } if (checkItem != null) { //找到,判断usertoken是否一样, 如果不一样,则表示不是同一个人,则为他人已连接 if (checkItem.UserToken != userToken) { //判断如果是同一个人,不同端 var checkItemReq = new WingInterfaceLibrary.Request.TokenRequest() { Token = checkItem.UserToken }; var checkItemToken = _authenticationService.GetTokenAsync(checkItemReq).Result; var userReq = new WingInterfaceLibrary.Request.TokenRequest() { Token = userToken }; var userTokenInfo = _authenticationService.GetTokenAsync(userReq).Result; //这两个一样,表示不同端登录 if (checkItemToken.ClientId == userTokenInfo.ClientId) { res = 2; } else { res = 1; } } //如果是同一个人,但是针对不同的模块也是不行的,比如正在会诊调参,是不能进行远程连接的 else if (checkItem.UserToken == userToken && checkItem.TransactionType != type) { res = 1; } } } return res; } /// /// 尝试关闭 /// /// public bool Close(string key) { if (_remoteConnects.ContainsKey(key)) { var res = _remoteConnects.TryRemove(key, out _); return res; } else { return false; } } /// /// 尝试关闭 /// /// public bool DeviceClose(string key) { if (_deviceRemoteConnects.ContainsKey(key)) { var res = _deviceRemoteConnects.TryRemove(key, out _); return res; } else { return false; } } /// /// 设备心跳有效期验证 /// private void StartCheckClients() { Logger.WriteLineInfo($"RemoteConnectManager start check clients"); Task.Run(async () => { while (true) { await Task.Delay(1 * 1000 * _rateSeconds); foreach (var token in _remoteConnects.Keys) { var remoteConnectDTO = _remoteConnects[token]; remoteConnectDTO.DeActivate(); try { if (remoteConnectDTO.LeftTime < 0) { Logger.WriteLineInfo($"RemoteConnectManager StartCheckClients, user is not online, Token:{ remoteConnectDTO.UserToken }, DeviceCode:{ remoteConnectDTO.DeviceCode }"); OnRemoteConnectOnlineState?.Invoke(remoteConnectDTO, remoteConnectDTO.IsNeedSyn, false); } } catch (Exception ex) { Logger.WriteLineWarn($"check remote connect token {token} err, {ex}"); } } foreach (var token in _deviceRemoteConnects.Keys) { var deviceRemoteConnectDTO = _deviceRemoteConnects[token]; deviceRemoteConnectDTO.DeActivate(); try { if (deviceRemoteConnectDTO.LeftTime < 0) { Logger.WriteLineInfo($"RemoteConnectManager StartCheckClients, device is not online, Token:{ deviceRemoteConnectDTO.DeviceToken }, UserCode:{ deviceRemoteConnectDTO.UserCode }"); OnDeviceRemoteConnectOnlineState?.Invoke(deviceRemoteConnectDTO, deviceRemoteConnectDTO.IsNeedSyn, false); } } catch (Exception ex) { Logger.WriteLineWarn($"check remote connect token {token} err, {ex}"); } } } }); Logger.WriteLineInfo($"RemoteConnectManager finished"); } } /// /// 远程连接管理实体 /// internal class RemoteConnectDTO { /// /// 有参构造 /// public RemoteConnectDTO(bool isNeedSyn, string userToken, string deviceToken, string deviceCode, string userCode, string roomId, ConnectStatusEnum statusEnum, TransactionTypeEnum transactionType, LoginSource loginSource) { UserToken = userToken; DeviceToken = deviceToken; DeviceCode = deviceCode; UserCode = userCode; RoomId = roomId; TransactionType = transactionType; StatusEnum = statusEnum; LoginSource = loginSource; IsNeedSyn = isNeedSyn; } /// /// 有参构造 /// public RemoteConnectDTO(string userToken, string deviceToken, string deviceCode, string userCode, string roomId, ConnectStatusEnum statusEnum, TransactionTypeEnum transactionType, LoginSource loginSource) { UserToken = userToken; DeviceToken = deviceToken; DeviceCode = deviceCode; UserCode = userCode; RoomId = roomId; TransactionType = transactionType; StatusEnum = statusEnum; LoginSource = loginSource; } /// /// 类型 /// public TransactionTypeEnum TransactionType { get; set; } /// /// 状态 /// public ConnectStatusEnum StatusEnum { get; set; } /// /// 用户Token /// public string UserToken { get; set; } /// /// 设备Token /// public string DeviceToken { get; set; } /// /// 用户code /// public string UserCode { get; set; } /// /// 房间id /// public string RoomId { get; set; } /// /// 设备code /// public string DeviceCode { get; set; } /// /// 是否需要同步数据处理 /// public bool IsNeedSyn { get; set; } /// /// 用户来源 /// /// public LoginSource LoginSource { get; set; } private volatile int _livingTime = 0; private readonly int _clientLifeCycle = 3; //3次无心跳就默认断开 /// /// 离开次数 /// public int LeftTime => _clientLifeCycle - _livingTime; /// /// Reset the living time. /// public virtual void Activate() { _livingTime = 0; } /// /// Deactive the session. /// public virtual void DeActivate() { _livingTime++; } } /// /// 设备远程连接管理实体 /// internal class DeviceRemoteConnectDTO { /// /// 有参构造 /// public DeviceRemoteConnectDTO(bool isNeedSyn, string deviceToken, string userToken, string userCode, string deviceCode, TransactionTypeEnum transactionType) { DeviceToken = deviceToken; UserToken = userToken; UserCode = userCode; DeviceCode = deviceCode; TransactionType = transactionType; IsNeedSyn = isNeedSyn; } /// /// 有参构造 /// public DeviceRemoteConnectDTO(string deviceToken, string userToken, string userCode, string deviceCode, TransactionTypeEnum transactionType) { DeviceToken = deviceToken; UserToken = userToken; UserCode = userCode; DeviceCode = deviceCode; TransactionType = transactionType; } /// /// 类型 /// public TransactionTypeEnum TransactionType { get; set; } /// /// 设备Token /// public string DeviceToken { get; set; } /// /// 用户Token /// public string UserToken { get; set; } /// /// 设备code /// public string DeviceCode { get; set; } /// /// 设备code /// public string UserCode { get; set; } /// /// 是否需要同步数据处理 /// public bool IsNeedSyn { get; set; } private volatile int _livingTime = 0; private readonly int _clientLifeCycle = 3; //3次无心跳就默认断开 /// /// 离开次数 /// public int LeftTime => _clientLifeCycle - _livingTime; /// /// Reset the living time. /// public virtual void Activate() { _livingTime = 0; } /// /// Deactive the session. /// public virtual void DeActivate() { _livingTime++; } } }