RPCServerTransport.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. namespace InABox.IPC
  2. {
  3. public abstract class RPCServerTransport<TConnection> : IRPCServerTransport where TConnection : notnull
  4. {
  5. private Dictionary<TConnection, RPCServerSession> _sessions = new Dictionary<TConnection, RPCServerSession>();
  6. protected RPCServerSession CreateSession(TConnection connection)
  7. {
  8. var session = new RPCServerSession();
  9. _sessions[connection] = session;
  10. return session;
  11. }
  12. protected RPCServerSession? GetSession(TConnection? connection)
  13. {
  14. if (connection == null)
  15. return null;
  16. _sessions.TryGetValue(connection, out RPCServerSession? session);
  17. return session;
  18. }
  19. protected RPCServerSession? DeleteSession(TConnection connection)
  20. {
  21. _sessions.Remove(connection, out RPCServerSession? session);
  22. return session;
  23. }
  24. private Dictionary<String, IRPCCommandHandler> _handlers = new Dictionary<String, IRPCCommandHandler>();
  25. public void AddHandler<TSender, TCommand, TProperties, TResult>(RPCCommandHandler<TSender, TProperties, TResult> handler)
  26. where TCommand : IRPCCommand<TProperties, TResult>
  27. where TSender : class
  28. {
  29. _handlers[typeof(TCommand).Name] = handler;
  30. }
  31. public abstract void Start();
  32. public abstract void Stop();
  33. public event RPCTransportOpenEvent? OnOpen;
  34. protected void DoOpen(TConnection connection)
  35. {
  36. var session = CreateSession(connection);
  37. OnOpen?.Invoke(this, new RPCTransportOpenArgs(session) );
  38. }
  39. public event RPCTransportCloseEvent? OnClose;
  40. protected void DoClose(TConnection connection , RPCTransportCloseEventType type)
  41. {
  42. var session = GetSession(connection);
  43. OnClose?.Invoke(this, new RPCTransportCloseArgs(session, type));
  44. }
  45. public event RPCTransportExceptionEvent? OnException;
  46. protected void DoException(TConnection? connection, Exception e)
  47. {
  48. var session = GetSession(connection);
  49. OnException?.Invoke(this, new RPCTransportExceptionArgs(session, e));
  50. }
  51. public event RPCTransportMessageEvent? BeforeMessage;
  52. protected void DoBeforeMessage(RPCServerSession? session, RPCMessage? message)
  53. {
  54. BeforeMessage?.Invoke(this, new RPCTransportMessageArgs(session,message));
  55. }
  56. public event RPCTransportMessageEvent? AfterMessage;
  57. protected void DoAfterMessage(RPCServerSession? session, RPCMessage? message)
  58. {
  59. AfterMessage?.Invoke(this, new RPCTransportMessageArgs(session,message));
  60. }
  61. public RPCMessage? DoMessage(TConnection? connection, RPCMessage? message)
  62. {
  63. var session = GetSession(connection);
  64. DoBeforeMessage(session,message);
  65. RPCMessage? response = null;
  66. if (session != null)
  67. {
  68. if (message != null)
  69. {
  70. response = new RPCMessage(message.ID, message.Command, "");
  71. if (_handlers.TryGetValue(message.Command, out var command))
  72. {
  73. try
  74. {
  75. response.Payload = command.Execute(message.Payload) ?? "";
  76. }
  77. catch (Exception err)
  78. {
  79. DoException(connection, err);
  80. response.Error = RPCError.SERVERERROR;
  81. }
  82. }
  83. else
  84. {
  85. DoException(connection, new Exception("Command Not Found"));
  86. response.Error = RPCError.COMMANDNOTFOUND;
  87. }
  88. DoAfterMessage(session, response);
  89. }
  90. else
  91. DoException(connection, new Exception("NULL Message Received"));
  92. }
  93. else
  94. DoException(connection, new Exception("Session not Found"));
  95. return response;
  96. }
  97. }
  98. }