FISIMPL.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. using FISLib;
  2. using FISLib.AfterSales;
  3. using FISLib.Connect;
  4. using FISLib.Consultation;
  5. using FISLib.Hardware;
  6. using FISLib.LiveVideo;
  7. using FISLib.Log;
  8. using FISLib.Notification;
  9. using FISLib.Remedical;
  10. using FISLib.Teaching;
  11. using FISLib.Test;
  12. using FISLib.Translator;
  13. using FISLib.Upgrade;
  14. using FISLib.Vid;
  15. using FISLib.vStation;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.IO;
  19. using System.Reflection;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Threading.Tasks;
  23. using Vinno.IUS.Common.Log;
  24. using Vinno.IUS.Common.Network;
  25. using Vinno.vCloud.Common.FIS.Log;
  26. using Vinno.vCloud.FIS.CrossPlatform.Common;
  27. using Vinno.vCloud.FIS.CrossPlatform.Common.Helper;
  28. namespace FISIMPL
  29. {
  30. public class FISIMPL
  31. {
  32. private static readonly Dictionary<Type, IService> _serviceDictionary = new Dictionary<Type, IService>();
  33. private static PipeServer _pipeServer;
  34. private static LogEngine _logEngine;
  35. private static Task _checkUltrasoundExeTask;
  36. private static CancellationTokenSource _cancellationTokenSource;
  37. /// <summary>
  38. /// Gets or sets if it is running in JsonRpc Mode
  39. /// </summary>
  40. internal static bool IsRunningJsonRpcMode { get; private set; }
  41. internal static UltrasoundMachineInfo UltrasoundMachineInfo { get; private set; }
  42. internal static FISPlatform Platform { get; private set; }
  43. public static bool IsConnectWithOldServer { get; private set; }
  44. public static string FISLogBasePath { get; private set; }
  45. /// <summary>
  46. /// Raised when close FIS Exe
  47. /// </summary>
  48. public static event EventHandler CloseFISExeEvent;
  49. public static void InitFISLogPath(string baseDirectory = null)
  50. {
  51. string logPath;
  52. if (string.IsNullOrEmpty(baseDirectory))
  53. {
  54. FISLogBasePath = AppDomain.CurrentDomain.BaseDirectory;
  55. }
  56. else
  57. {
  58. FISLogBasePath = baseDirectory;
  59. }
  60. logPath = Path.Combine(FISLogBasePath, "FISLogs");
  61. DirectoryHelper.CreateDirectory(logPath);
  62. CommonInitializer.Initialize(logPath);
  63. if (_logEngine == null)
  64. {
  65. _logEngine = new FISLogEngine();
  66. Logger.RegisterEngine(_logEngine);
  67. CrossPlatformHelper.Instance.LogWriter = new LogWriter();
  68. }
  69. }
  70. public static void InitLogEngine(LogEngine logEngine)
  71. {
  72. if (_logEngine == null)
  73. {
  74. _logEngine = logEngine;
  75. Logger.RegisterEngine(_logEngine);
  76. CrossPlatformHelper.Instance.LogWriter = new LogWriter();
  77. }
  78. }
  79. /// <summary>
  80. /// Star the FISIMPL in Windows/Android.
  81. /// </summary>
  82. public static void Start(string machineId, FISPlatform platform = FISPlatform.Windows, bool isRunningJsonRpcMode = true)
  83. {
  84. try
  85. {
  86. Logger.WriteLineInfo("Ready To Start FISIMPL");
  87. AppDomain.CurrentDomain.UnhandledException += OnDomainOnUnhandledException;
  88. if (machineId.Length > 1)
  89. {
  90. CommonParameter.Instance.MachineId = machineId;
  91. }
  92. else
  93. {
  94. CommonParameter.Instance.MachineId = "Unknown";
  95. }
  96. Platform = platform;
  97. IsRunningJsonRpcMode = isRunningJsonRpcMode;
  98. var currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
  99. Logger.WriteLineInfo($"FISIMPL Current Version is{currentVersion}");
  100. RegisterServices();
  101. FIS.FISLogInfoNotificated += OnFISLogInfoNotificated;
  102. if (IsRunningJsonRpcMode)
  103. {
  104. switch (Platform)
  105. {
  106. case FISPlatform.Windows:
  107. StartInWindows();
  108. break;
  109. case FISPlatform.Android:
  110. StartInAndroid();
  111. break;
  112. }
  113. }
  114. }
  115. catch (Exception ex)
  116. {
  117. Logger.WriteLineError($"FISIMPL Start Error,{ex}");
  118. DisposePipeServer();
  119. throw;
  120. }
  121. }
  122. public static void ChangeMachineId(string machineId)
  123. {
  124. if (!string.IsNullOrEmpty(machineId))
  125. {
  126. CommonParameter.Instance.MachineId = machineId;
  127. }
  128. }
  129. private static void OnFISLogInfoNotificated(object sender, FISLogEventArgs e)
  130. {
  131. Logger.WriteLineWarn($"OnFISLogInfoNotificated Invoke {e.Msg}");
  132. }
  133. private static void RegisterServices()
  134. {
  135. switch (Platform)
  136. {
  137. case FISPlatform.Windows:
  138. var connectionService = new ConnectionService();
  139. _serviceDictionary.Add(typeof(IConnectionService), connectionService);
  140. var remedicalService = new RemedicalService();
  141. _serviceDictionary.Add(typeof(IRemedicalService), remedicalService);
  142. var vStationService = new VStationService();
  143. _serviceDictionary.Add(typeof(IvStationService), vStationService);
  144. var vidServiceForWindows = new VidServiceForWindows();
  145. _serviceDictionary.Add(typeof(IVidService), vidServiceForWindows);
  146. var translatorService = new TranslatorService();
  147. _serviceDictionary.Add(typeof(ITranslatorService), translatorService);
  148. var upgraderService = new UpgraderService();
  149. _serviceDictionary.Add(typeof(IUpgraderService), upgraderService);
  150. var teachingService = new TeachingService();
  151. _serviceDictionary.Add(typeof(ITeachingService), teachingService);
  152. var liveVideoServiceForWindows = new LiveVideoServiceForWindows();
  153. _serviceDictionary.Add(typeof(ILiveVideoService), liveVideoServiceForWindows);
  154. //var logService = new LogService();
  155. //_serviceDictionary.Add(typeof(ILogService), logService);
  156. var testService = new TestService();
  157. _serviceDictionary.Add(typeof(ITestService), testService);
  158. var consultationServiceForWindows = new ConsultationServiceForWindows();
  159. _serviceDictionary.Add(typeof(IConsultationService), consultationServiceForWindows);
  160. var afterSalesService = new AfterSalesService();
  161. _serviceDictionary.Add(typeof(IAfterSalesService), afterSalesService);
  162. var hardwareServiceForWindows = new HardwareServiceForWindows();
  163. _serviceDictionary.Add(typeof(IHardwareService), hardwareServiceForWindows);
  164. break;
  165. case FISPlatform.Android:
  166. connectionService = new ConnectionService();
  167. _serviceDictionary.Add(typeof(IConnectionService), connectionService);
  168. remedicalService = new RemedicalService();
  169. _serviceDictionary.Add(typeof(IRemedicalService), remedicalService);
  170. vStationService = new VStationService();
  171. _serviceDictionary.Add(typeof(IvStationService), vStationService);
  172. var vidServiceForAndroid = new VidServiceForAndroid();
  173. _serviceDictionary.Add(typeof(IVidService), vidServiceForAndroid);
  174. translatorService = new TranslatorService();
  175. _serviceDictionary.Add(typeof(ITranslatorService), translatorService);
  176. upgraderService = new UpgraderService();
  177. _serviceDictionary.Add(typeof(IUpgraderService), upgraderService);
  178. teachingService = new TeachingService();
  179. _serviceDictionary.Add(typeof(ITeachingService), teachingService);
  180. var liveVideoServiceForAndroid = new LiveVideoServiceForAndroid();
  181. _serviceDictionary.Add(typeof(ILiveVideoService), liveVideoServiceForAndroid);
  182. //logService = new LogService();
  183. //_serviceDictionary.Add(typeof(ILogService), logService);
  184. testService = new TestService();
  185. _serviceDictionary.Add(typeof(ITestService), testService);
  186. var consultationServiceForAndroid = new ConsultationServiceForAndroid();
  187. _serviceDictionary.Add(typeof(IConsultationService), consultationServiceForAndroid);
  188. afterSalesService = new AfterSalesService();
  189. _serviceDictionary.Add(typeof(IAfterSalesService), afterSalesService);
  190. var hardwareServiceForAndroid = new HardwareServiceForAndroid();
  191. _serviceDictionary.Add(typeof(IHardwareService), hardwareServiceForAndroid);
  192. break;
  193. }
  194. }
  195. public static T GetService<T>() where T : IService
  196. {
  197. var type = typeof(T);
  198. if (_serviceDictionary.ContainsKey(type))
  199. {
  200. return (T)_serviceDictionary[type];
  201. }
  202. throw new NullReferenceException($"Can not find instance for type{type}");
  203. }
  204. internal static void DisposeAllService()
  205. {
  206. foreach (var service in _serviceDictionary)
  207. {
  208. try
  209. {
  210. if (service.Value is IDisposable dispose)
  211. {
  212. dispose.Dispose();
  213. }
  214. }
  215. catch (Exception e)
  216. {
  217. Logger.WriteLineError($"Dispose Service {service.Key} failed, ex: {e}");
  218. }
  219. }
  220. _serviceDictionary.Clear();
  221. Logger.WriteLineInfo($"FISIMPL DisposeAllService success");
  222. }
  223. /// <summary>
  224. /// Stop the FISIMPL
  225. /// </summary>
  226. public static void Stop()
  227. {
  228. Logger.WriteLineInfo("FISIMPL Stop Invoke");
  229. _cancellationTokenSource?.Cancel();
  230. try
  231. {
  232. _checkUltrasoundExeTask?.Wait(1000);//因Task在Wait过程中Cancel有几率会出错
  233. }
  234. catch
  235. {
  236. }
  237. DisposeAllService();
  238. if (IsRunningJsonRpcMode)
  239. {
  240. FISJsonRpcServer.Stop();
  241. NotificationSender.Dispose();
  242. }
  243. if (_logEngine != null)
  244. {
  245. _logEngine.Dispose();
  246. _logEngine = null;
  247. }
  248. AppDomain.CurrentDomain.UnhandledException -= OnDomainOnUnhandledException;
  249. FIS.FISLogInfoNotificated -= OnFISLogInfoNotificated;
  250. }
  251. public static void SetIsConnectWithOldServer(bool isConnectWithOldServer)
  252. {
  253. IsConnectWithOldServer = isConnectWithOldServer;
  254. NotificationSender.SendNotification(new FISNotificationArgs
  255. {
  256. NotificationType = FISNotificationType.FISConnectIsConnectWithOldServer,
  257. Params = isConnectWithOldServer,
  258. });
  259. }
  260. public static void SetUltrasoundMachineInfo(UltrasoundMachineInfo ultrasoundMachineInfo)
  261. {
  262. UltrasoundMachineInfo = ultrasoundMachineInfo;
  263. }
  264. private static void StartInWindows()
  265. {
  266. string processName = null;
  267. FISJsonRpcServer.Start();
  268. NotificationSender.Initialize();
  269. CreatePipeServer();
  270. Logger.WriteLineInfo($"FISMPL Start to Pair with Ultrasonic Software");
  271. if (_pipeServer.Start(60000))
  272. {
  273. Logger.WriteLineInfo($"FISMPL Pair Success");
  274. var processNameBytes = _pipeServer.ReceiveBytes();
  275. processName = Encoding.Unicode.GetString(processNameBytes);
  276. DisposePipeServer();
  277. }
  278. else
  279. {
  280. Logger.WriteLineError($"FISMPL Pair Fail");
  281. DisposePipeServer();
  282. Logger.WriteLineError($"CloseFISExeEvent Start to Invoke");
  283. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  284. return;
  285. }
  286. if (string.IsNullOrWhiteSpace(processName))
  287. {
  288. Logger.WriteLineError($"FISMPL The ProcessName is empty,CloseFISExeEvent Start to Invoke");
  289. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  290. return;
  291. }
  292. _cancellationTokenSource = new CancellationTokenSource();
  293. _checkUltrasoundExeTask = new Task(() =>
  294. {
  295. while (!_cancellationTokenSource.IsCancellationRequested)
  296. {
  297. try
  298. {
  299. if (!CheckIsUltrasoundExeExist(processName))
  300. {
  301. Logger.WriteLineError($"FISMPL checkUltrasoundExe Task:The UltrasoundExe is not Exist,it will Close");
  302. _cancellationTokenSource.Cancel();
  303. ProcessHelper.FinishProcessByName("Vinno.FIS.TRTCClient");
  304. Task.Run(() =>//之所以起Task,是因为Stop的时候会wait checkUltrasoundExeTask.
  305. {
  306. Logger.WriteLineError($"CloseFISExeEvent Start to Invoke");
  307. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  308. });
  309. }
  310. else
  311. {
  312. Thread.Sleep(1000);
  313. }
  314. }
  315. catch (Exception ex)
  316. {
  317. Logger.WriteLineError($"CheckUltrasoundExe Task Error:{ex}");
  318. }
  319. }
  320. }, _cancellationTokenSource.Token);
  321. _checkUltrasoundExeTask.Start();
  322. Logger.WriteLineInfo($"FISMPL Start checkUltrasoundExe Task");
  323. }
  324. public static void WriterLineInfo(string msg)
  325. {
  326. Logger.WriteLineInfo(msg);
  327. }
  328. public static void WriteLineWarn(string msg)
  329. {
  330. Logger.WriteLineWarn(msg);
  331. }
  332. public static void WriteLineError(string msg)
  333. {
  334. Logger.WriteLineError(msg);
  335. }
  336. private static void CreatePipeServer()
  337. {
  338. if (_pipeServer == null)
  339. {
  340. _pipeServer = new PipeServer(FISConsts.PipeForFISExeBootUpCheck);
  341. _pipeServer.LogMsgThrow += OnLogMsgThrow;
  342. }
  343. Logger.WriteLineInfo($"CreatePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success");
  344. }
  345. private static void DisposePipeServer()
  346. {
  347. if (_pipeServer != null)
  348. {
  349. _pipeServer.Dispose();
  350. _pipeServer.LogMsgThrow -= OnLogMsgThrow;
  351. _pipeServer = null;
  352. }
  353. Logger.WriteLineInfo($"DisposePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success");
  354. }
  355. private static void OnLogMsgThrow(object sender, FISLogEventArgs e)
  356. {
  357. if (e == null)
  358. {
  359. return;
  360. }
  361. switch (e.LogType)
  362. {
  363. case FISDeviceLogCategory.Error:
  364. Logger.WriteLineError(e.Msg);
  365. break;
  366. case FISDeviceLogCategory.Warn:
  367. Logger.WriteLineWarn(e.Msg);
  368. break;
  369. case FISDeviceLogCategory.Verb:
  370. Logger.WriteLineVerbose(e.Msg);
  371. break;
  372. case FISDeviceLogCategory.Info:
  373. default:
  374. Logger.WriteLineInfo(e.Msg);
  375. break;
  376. }
  377. }
  378. private static void StartInAndroid()
  379. {
  380. FISJsonRpcServer.Start();
  381. NotificationSender.Initialize();
  382. }
  383. private static void OnDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
  384. {
  385. Logger.WriteLineError($"OnDomainOnUnhandledException:{e.ExceptionObject}");
  386. }
  387. private static bool CheckIsUltrasoundExeExist(string processName)
  388. {
  389. return ProcessHelper.IsProcessExistByName(processName);
  390. }
  391. public static void WriteInfoLog(string logMsg)
  392. {
  393. Logger.WriteLineInfo(logMsg);
  394. }
  395. public static void WriteErrorLog(string logMsg)
  396. {
  397. Logger.WriteLineError(logMsg);
  398. }
  399. public static void WriteWarnLog(string logMsg)
  400. {
  401. Logger.WriteLineWarn(logMsg);
  402. }
  403. }
  404. }