LogikalClient.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using H.Formatters;
  6. using H.Pipes;
  7. using InABox.Core;
  8. using InABox.IPC;
  9. using InABox.Logikal;
  10. using java.lang;
  11. using Exception = System.Exception;
  12. using Process = System.Diagnostics.Process;
  13. namespace PRSDesktop;
  14. public class LogikalClient : IDisposable, ILogikalApp
  15. {
  16. private readonly PipeClient<LogikalMessage> _client;
  17. private ConcurrentDictionary<Guid, ManualResetEventSlim> Events = new();
  18. private ConcurrentDictionary<Guid, LogikalMessage> Responses = new();
  19. private const int DefaultRequestTimeout = 5 * 60 * 1000; // 5 minutes
  20. public LogikalClient()
  21. {
  22. var _basedirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? "";
  23. var _logikalapp = System.IO.Path.Combine(_basedirectory, "PRSLogikal", "PRSLogikal.exe");
  24. Process.Start(_logikalapp);
  25. _client = new PipeClient<LogikalMessage>("$logikal", formatter: new NewtonsoftJsonFormatter());
  26. _client.Connected += Client_Connected;
  27. _client.Disconnected += Client_Disconnected;
  28. _client.MessageReceived += Client_MessageReceived;
  29. _client.ExceptionOccurred += Client_ExceptionOccurred;
  30. _client.ConnectAsync();
  31. }
  32. public void Dispose()
  33. {
  34. _client.DisposeAsync().AsTask().Wait();
  35. }
  36. private void Client_Connected(object? sender, H.Pipes.Args.ConnectionEventArgs<LogikalMessage> e)
  37. {
  38. Logger.Send(LogType.Information, "", $"Connected to Pipe: {e.Connection.PipeName}");
  39. //Disconnected = false;
  40. // Here we will register a Licence "Hit" for the Logikal interface
  41. }
  42. private void Client_Disconnected(object? sender, H.Pipes.Args.ConnectionEventArgs<LogikalMessage> e)
  43. {
  44. Logger.Send(LogType.Information, "", $"Disconnected from Pipe: {e.Connection.PipeName}");
  45. foreach (var ev in Events)
  46. {
  47. Responses.TryAdd(ev.Key, LogikalMessage.Error("Disconnected"));
  48. ev.Value.Set();
  49. }
  50. //Disconnected = true;
  51. }
  52. private void Client_ExceptionOccurred(object? sender, H.Pipes.Args.ExceptionEventArgs e)
  53. {
  54. Logger.Send(LogType.Error, "", $"Exception occured: {e.Exception.Message}");
  55. }
  56. public LogikalResponse Send(LogikalRequest request, int timeout = DefaultRequestTimeout)
  57. {
  58. var message = new LogikalMessage()
  59. {
  60. ID = Guid.NewGuid(),
  61. Method = request.Method(),
  62. Payload = Serialization.Serialize(request),
  63. };
  64. var ev = Queue(message.ID);
  65. _client.WriteAsync(message);
  66. var result = GetResult(message.ID, ev, timeout);
  67. return LogikalResponse.FromMessage(result);
  68. }
  69. public ManualResetEventSlim Queue(Guid id)
  70. {
  71. var ev = new ManualResetEventSlim();
  72. Events[id] = ev;
  73. return ev;
  74. }
  75. public LogikalMessage GetResult(Guid id, ManualResetEventSlim ev, int timeout)
  76. {
  77. if (Responses.TryRemove(id, out var result))
  78. {
  79. Events.TryRemove(id, out ev);
  80. return result;
  81. }
  82. try
  83. {
  84. if (!ev.Wait(timeout))
  85. {
  86. return LogikalMessage.Error("Timeout");
  87. }
  88. }
  89. catch (Exception e)
  90. {
  91. Console.WriteLine(e);
  92. throw;
  93. }
  94. Responses.TryRemove(id, out result);
  95. Events.TryRemove(id, out ev);
  96. return result ?? LogikalMessage.Error("Unknown");
  97. }
  98. private void Client_MessageReceived(object? sender, H.Pipes.Args.ConnectionMessageEventArgs<LogikalMessage?> e)
  99. {
  100. if (Events.TryGetValue(e.Message.ID, out var ev))
  101. {
  102. Responses[e.Message.ID] = e.Message;
  103. ev.Set();
  104. }
  105. }
  106. ~LogikalClient()
  107. {
  108. Dispose();
  109. }
  110. public LogikalStatus Connect(string path)
  111. {
  112. var request = new LogikalConnectRequest() { Path = path };
  113. var result = Send(request);
  114. return result.Status;
  115. }
  116. public LogikalStatus Disconnect()
  117. {
  118. var request = new LogikalDisconnectRequest();
  119. var result = Send(request);
  120. return result.Status;
  121. }
  122. public LogikalStatus Login(string username, string password)
  123. {
  124. var request = new LogikalLoginRequest() { UserID = username, Password = password };
  125. var result = Send(request);
  126. return result.Status;
  127. }
  128. public LogikalStatus Logout()
  129. {
  130. var request = new LogikalLogoutRequest();
  131. var result = Send(request);
  132. return result.Status;
  133. }
  134. }