LogikalListener.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using System;
  2. using System.Collections.Generic;
  3. using H.Formatters;
  4. using H.Pipes;
  5. using InABox.Integration.Logikal;
  6. using Newtonsoft.Json;
  7. namespace PRSLogikal
  8. {
  9. public class LogikalListener : IDisposable
  10. {
  11. private PipeServer<LogikalMessage> _server;
  12. public LogikalServer Server { get; set; }
  13. public event LogikalLogEvent Log;
  14. private void DoLog(string message) => Log?.Invoke(this, new LogikalLogArguments(message));
  15. public event EventHandler Disconnecting;
  16. public LogikalListener()
  17. {
  18. methods = new Dictionary<LogikalMethod, ILogikalMethodInfo>
  19. {
  20. { LogikalMethod.Error, new LogikalMethodInfo<LogikalErrorRequest>(DoError) },
  21. { LogikalMethod.Connect, new LogikalMethodInfo<LogikalConnectRequest>(Connect) },
  22. { LogikalMethod.Login, new LogikalMethodInfo<LogikalLoginRequest>(Login) },
  23. { LogikalMethod.Logout, new LogikalMethodInfo<LogikalLogoutRequest>(Logout) },
  24. { LogikalMethod.Disconnect, new LogikalMethodInfo<LogikalDisconnectRequest>(Disconnect) },
  25. { LogikalMethod.ProjectCentres, new LogikalMethodInfo<LogikalProjectCentresRequest>(GetProjectCentres) },
  26. { LogikalMethod.Projects, new LogikalMethodInfo<LogikalProjectsRequest>(GetProjects) },
  27. { LogikalMethod.Phases, new LogikalMethodInfo<LogikalPhasesRequest>(GetPhases) },
  28. { LogikalMethod.ElevationSummary, new LogikalMethodInfo<LogikalElevationSummaryRequest>(GetElevationSummaries) },
  29. { LogikalMethod.ElevationDetail, new LogikalMethodInfo<LogikalElevationDetailRequest>(GetElevationDetails) },
  30. { LogikalMethod.BOM, new LogikalMethodInfo<LogikalBOMRequest>(GetBOM) },
  31. };
  32. _server = new PipeServer<LogikalMessage>("$logikal", new MessagePackFormatter<LogikalMessage>());
  33. _server.ClientConnected += (o, args) =>
  34. {
  35. DoLog($@"Client is now connected!");
  36. };
  37. _server.ClientDisconnected += (o, args) =>
  38. {
  39. DoLog($@"Client disconnected");
  40. };
  41. _server.MessageReceived += (sender, args) =>
  42. {
  43. DoLog($@"Client says: {args.Message.Method}: {args.Message.Payload}");
  44. if (methods.TryGetValue(args.Message.Method, out var _info))
  45. {
  46. var _request = FromMessage(_info.Type, args.Message);
  47. _info.Action(_request, args.Message.ID);
  48. }
  49. else
  50. DoError(new LogikalErrorRequest(LogikalStatus.Error, $"Invalid Message Method: {args.Message.Method}: {args.Message.Payload}"), args.Message.ID);
  51. };
  52. _server.ExceptionOccurred += (sender, args) =>
  53. {
  54. DoLog($@"Exception: {args.Exception.Message}");
  55. };
  56. }
  57. private interface ILogikalMethodInfo
  58. {
  59. Type Type { get; }
  60. Action<LogikalRequest,Guid> Action { get; }
  61. }
  62. private class LogikalMethodInfo<T> : ILogikalMethodInfo where T : LogikalRequest
  63. {
  64. public Type Type { get; }
  65. public Action<LogikalRequest, Guid> Action { get; private set; }
  66. public LogikalMethodInfo(Action<T, Guid> action)
  67. {
  68. Type = typeof(T);
  69. Action = (request,id) => action(request as T,id);
  70. }
  71. }
  72. private Dictionary<LogikalMethod, ILogikalMethodInfo> methods;
  73. private LogikalRequest FromMessage(Type type, LogikalMessage message)
  74. {
  75. try
  76. {
  77. LogikalRequest _result = null;
  78. _result = JsonConvert.DeserializeObject(message.Payload, type) as LogikalRequest;
  79. if (_result != null)
  80. return _result;
  81. return new LogikalErrorRequest() { Status = LogikalStatus.Error, Message = $"Deserialize Failure: {message.Method}: {message.Payload}" };
  82. }
  83. catch (Exception e)
  84. {
  85. return new LogikalErrorRequest() { Status = LogikalStatus.Error, Message = $"Exception Deserializing Request: {e.Message}\n{e.StackTrace}" };
  86. }
  87. }
  88. public void Start() => _server.StartAsync();
  89. public void Stop() => _server.StopAsync();
  90. private void DoError(LogikalErrorRequest request, Guid messageID)
  91. {
  92. var _response = new LogikalErrorResponse() { Status = request.Status, Message = request.Message };
  93. DoLog($"Server replies: {_response.ToString()}");
  94. _server.WriteAsync(_response.ToMessage(messageID));
  95. }
  96. private void Connect(LogikalConnectRequest request, Guid messageID)
  97. {
  98. var _response = Server.Connect(request);
  99. DoLog($"Server replies: {_response.ToString()}");
  100. _server.WriteAsync(_response.ToMessage(messageID));
  101. }
  102. private void Disconnect(LogikalDisconnectRequest request, Guid messageID)
  103. {
  104. var _response = Server.Disconnect();
  105. DoLog($"Server replies: {_response.ToString()}");
  106. _server.WriteAsync(_response.ToMessage(messageID));
  107. Disconnecting?.Invoke(this,EventArgs.Empty);
  108. }
  109. private void Login(LogikalLoginRequest request, Guid messageID)
  110. {
  111. var _response = Server.Login(request);
  112. DoLog($"Server replies: {_response.ToString()}");
  113. _server.WriteAsync(_response.ToMessage(messageID));
  114. }
  115. private void Logout(LogikalLogoutRequest request, Guid messageID)
  116. {
  117. var _response = Server.Logout();
  118. DoLog($"Server replies: {_response.ToString()}");
  119. _server.WriteAsync(_response.ToMessage(messageID));
  120. }
  121. private void GetProjectCentres(LogikalProjectCentresRequest request, Guid messageID)
  122. {
  123. var _response = Server.GetProjectCentres(request);
  124. DoLog($"Server replies: {_response.ToString()}");
  125. _server.WriteAsync(_response.ToMessage(messageID));
  126. }
  127. private void GetProjects(LogikalProjectsRequest request, Guid messageID)
  128. {
  129. var _response = Server.GetProjects(request);
  130. DoLog($"Server replies: {_response.ToString()}");
  131. _server.WriteAsync(_response.ToMessage(messageID));
  132. }
  133. private void GetProject(LogikalProjectRequest request, Guid messageID)
  134. {
  135. var _response = Server.GetProject(request);
  136. DoLog($"Server replies: {_response.ToString()}");
  137. _server.WriteAsync(_response.ToMessage(messageID));
  138. }
  139. private void GetPhases(LogikalPhasesRequest request, Guid messageID)
  140. {
  141. var _response = Server.GetPhases(request);
  142. DoLog($"Server replies: {_response.ToString()}");
  143. _server.WriteAsync(_response.ToMessage(messageID));
  144. }
  145. private void GetBOM(LogikalBOMRequest request, Guid messageID)
  146. {
  147. var _response = Server.GetBillOfMaterials(request);
  148. DoLog($"Server replies: {_response.ToString()}");
  149. _server.WriteAsync(_response.ToMessage(messageID));
  150. }
  151. private void GetElevationSummaries(LogikalElevationSummaryRequest request, Guid messageID)
  152. {
  153. var _response = Server.GetElevationSummaries(request);
  154. DoLog($"Server replies: {_response.ToString()}");
  155. _server.WriteAsync(_response.ToMessage(messageID));
  156. }
  157. private void GetElevationDetails(LogikalElevationDetailRequest detailRequest, Guid messageID)
  158. {
  159. var _response = Server.GetElevationDetails(detailRequest);
  160. DoLog($"Server replies: {_response.ToString()}");
  161. _server.WriteAsync(_response.ToMessage(messageID));
  162. }
  163. public void Dispose()
  164. {
  165. if (_server != null)
  166. _ = _server.DisposeAsync().AsTask();
  167. }
  168. }
  169. }