LogikalListener.cs 8.0 KB

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