FISIMPL.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  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. internal 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 IConnectionService connectionService)
  211. {
  212. connectionService.Dispose();
  213. }
  214. if (service.Value is IAfterSalesService afterSalesService)
  215. {
  216. afterSalesService.Dispose();
  217. }
  218. if (service.Value is IConsultationService consultationService)
  219. {
  220. consultationService.Dispose();
  221. }
  222. if (service.Value is IHardwareService hardwareService)
  223. {
  224. hardwareService.Dispose();
  225. }
  226. if (service.Value is ILiveVideoService liveVideoService)
  227. {
  228. liveVideoService.Dispose();
  229. }
  230. if (service.Value is ILogService logService)
  231. {
  232. logService.Dispose();
  233. }
  234. if (service.Value is IRemedicalService remedicalService)
  235. {
  236. remedicalService.Dispose();
  237. }
  238. if (service.Value is ITeachingService teachingService)
  239. {
  240. teachingService.Dispose();
  241. }
  242. if (service.Value is ITestService testService)
  243. {
  244. testService.Dispose();
  245. }
  246. if (service.Value is IUpgraderService upgraderService)
  247. {
  248. upgraderService.Dispose();
  249. }
  250. if (service.Value is IVidService vidService)
  251. {
  252. vidService.Dispose();
  253. }
  254. if (service.Value is IvStationService vstationService)
  255. {
  256. vstationService.Dispose();
  257. }
  258. }
  259. catch (Exception e)
  260. {
  261. Logger.WriteLineError($"Dispose Service {service.Key} failed, ex: {e}");
  262. }
  263. }
  264. _serviceDictionary.Clear();
  265. Logger.WriteLineInfo($"FISIMPL DisposeAllService success");
  266. }
  267. /// <summary>
  268. /// Stop the FISIMPL
  269. /// </summary>
  270. public static void Stop()
  271. {
  272. Logger.WriteLineInfo("FISIMPL Stop Invoke");
  273. _cancellationTokenSource?.Cancel();
  274. try
  275. {
  276. _checkUltrasoundExeTask?.Wait(1000);//因Task在Wait过程中Cancel有几率会出错
  277. }
  278. catch
  279. {
  280. }
  281. DisposeAllService();
  282. if (IsRunningJsonRpcMode)
  283. {
  284. FISJsonRpcServer.Stop();
  285. NotificationSender.Dispose();
  286. }
  287. if (_logEngine != null)
  288. {
  289. _logEngine.Dispose();
  290. _logEngine = null;
  291. }
  292. AppDomain.CurrentDomain.UnhandledException -= OnDomainOnUnhandledException;
  293. FIS.FISLogInfoNotificated -= OnFISLogInfoNotificated;
  294. }
  295. public static void SetIsConnectWithOldServer(bool isConnectWithOldServer)
  296. {
  297. IsConnectWithOldServer = isConnectWithOldServer;
  298. NotificationSender.SendNotification(new FISNotificationArgs
  299. {
  300. NotificationType = FISNotificationType.FISConnectIsConnectWithOldServer,
  301. Params = isConnectWithOldServer,
  302. });
  303. }
  304. public static void SetUltrasoundMachineInfo(UltrasoundMachineInfo ultrasoundMachineInfo)
  305. {
  306. UltrasoundMachineInfo = ultrasoundMachineInfo;
  307. }
  308. private static void StartInWindows()
  309. {
  310. string processName = null;
  311. FISJsonRpcServer.Start();
  312. NotificationSender.Initialize();
  313. CreatePipeServer();
  314. Logger.WriteLineInfo($"FISMPL Start to Pair with Ultrasonic Software");
  315. if (_pipeServer.Start(60000))
  316. {
  317. Logger.WriteLineInfo($"FISMPL Pair Success");
  318. var processNameBytes = _pipeServer.ReceiveBytes();
  319. processName = Encoding.Unicode.GetString(processNameBytes);
  320. DisposePipeServer();
  321. }
  322. else
  323. {
  324. Logger.WriteLineError($"FISMPL Pair Fail");
  325. DisposePipeServer();
  326. Logger.WriteLineError($"CloseFISExeEvent Start to Invoke");
  327. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  328. return;
  329. }
  330. if (string.IsNullOrWhiteSpace(processName))
  331. {
  332. Logger.WriteLineError($"FISMPL The ProcessName is empty,CloseFISExeEvent Start to Invoke");
  333. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  334. return;
  335. }
  336. _cancellationTokenSource = new CancellationTokenSource();
  337. _checkUltrasoundExeTask = new Task(() =>
  338. {
  339. while (!_cancellationTokenSource.IsCancellationRequested)
  340. {
  341. try
  342. {
  343. if (!CheckIsUltrasoundExeExist(processName))
  344. {
  345. Logger.WriteLineError($"FISMPL checkUltrasoundExe Task:The UltrasoundExe is not Exist,it will Close");
  346. _cancellationTokenSource.Cancel();
  347. ProcessHelper.FinishProcessByName("Vinno.FIS.TRTCClient");
  348. Task.Run(() =>//之所以起Task,是因为Stop的时候会wait checkUltrasoundExeTask.
  349. {
  350. Logger.WriteLineError($"CloseFISExeEvent Start to Invoke");
  351. CloseFISExeEvent?.Invoke(null, EventArgs.Empty);
  352. });
  353. }
  354. else
  355. {
  356. Thread.Sleep(1000);
  357. }
  358. }
  359. catch (Exception ex)
  360. {
  361. Logger.WriteLineError($"CheckUltrasoundExe Task Error:{ex}");
  362. }
  363. }
  364. }, _cancellationTokenSource.Token);
  365. _checkUltrasoundExeTask.Start();
  366. Logger.WriteLineInfo($"FISMPL Start checkUltrasoundExe Task");
  367. }
  368. public static void WriterLineInfo(string msg)
  369. {
  370. Logger.WriteLineInfo(msg);
  371. }
  372. public static void WriteLineWarn(string msg)
  373. {
  374. Logger.WriteLineWarn(msg);
  375. }
  376. public static void WriteLineError(string msg)
  377. {
  378. Logger.WriteLineError(msg);
  379. }
  380. private static void CreatePipeServer()
  381. {
  382. if (_pipeServer == null)
  383. {
  384. _pipeServer = new PipeServer(FISConsts.PipeForFISExeBootUpCheck);
  385. _pipeServer.LogMsgThrow += OnLogMsgThrow;
  386. }
  387. Logger.WriteLineInfo($"CreatePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success");
  388. }
  389. private static void DisposePipeServer()
  390. {
  391. if (_pipeServer != null)
  392. {
  393. _pipeServer.Dispose();
  394. _pipeServer.LogMsgThrow -= OnLogMsgThrow;
  395. _pipeServer = null;
  396. }
  397. Logger.WriteLineInfo($"DisposePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success");
  398. }
  399. private static void OnLogMsgThrow(object sender, FISLogEventArgs e)
  400. {
  401. if (e == null)
  402. {
  403. return;
  404. }
  405. switch (e.LogType)
  406. {
  407. case FISDeviceLogCategory.Error:
  408. Logger.WriteLineError(e.Msg);
  409. break;
  410. case FISDeviceLogCategory.Warn:
  411. Logger.WriteLineWarn(e.Msg);
  412. break;
  413. case FISDeviceLogCategory.Verb:
  414. Logger.WriteLineVerbose(e.Msg);
  415. break;
  416. case FISDeviceLogCategory.Info:
  417. default:
  418. Logger.WriteLineInfo(e.Msg);
  419. break;
  420. }
  421. }
  422. private static void StartInAndroid()
  423. {
  424. FISJsonRpcServer.Start();
  425. NotificationSender.Initialize();
  426. }
  427. private static void OnDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
  428. {
  429. Logger.WriteLineError($"OnDomainOnUnhandledException:{e.ExceptionObject}");
  430. }
  431. private static bool CheckIsUltrasoundExeExist(string processName)
  432. {
  433. return ProcessHelper.IsProcessExistByName(processName);
  434. }
  435. public static void WriteInfoLog(string logMsg)
  436. {
  437. Logger.WriteLineInfo(logMsg);
  438. }
  439. public static void WriteErrorLog(string logMsg)
  440. {
  441. Logger.WriteLineError(logMsg);
  442. }
  443. public static void WriteWarnLog(string logMsg)
  444. {
  445. Logger.WriteLineWarn(logMsg);
  446. }
  447. }
  448. }