MessageLocationHandler.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using System;
  2. namespace ET.Server
  3. {
  4. public abstract class MessageLocationHandler<E, Message>: HandlerObject, IMHandler where E : Entity where Message : class, ILocationMessage
  5. {
  6. protected abstract ETTask Run(E entity, Message message);
  7. public async ETTask Handle(Entity entity, Address fromAddress, MessageObject actorMessage)
  8. {
  9. Fiber fiber = entity.Fiber();
  10. if (actorMessage is not Message message)
  11. {
  12. Log.Error($"消息类型转换错误: {actorMessage.GetType().FullName} to {typeof (Message).Name}");
  13. return;
  14. }
  15. if (entity is not E e)
  16. {
  17. Log.Error($"Actor类型转换错误: {entity.GetType().FullName} to {typeof (E).FullName} --{typeof (Message).FullName}");
  18. return;
  19. }
  20. MessageResponse response = ObjectPool.Fetch<MessageResponse>();
  21. response.RpcId = message.RpcId;
  22. fiber.Root.GetComponent<ProcessInnerSender>().Reply(fromAddress, response);
  23. await this.Run(e, message);
  24. }
  25. public Type GetRequestType()
  26. {
  27. return typeof (Message);
  28. }
  29. public Type GetResponseType()
  30. {
  31. return typeof (MessageResponse);
  32. }
  33. }
  34. public abstract class MessageLocationHandler<E, Request, Response>: HandlerObject, IMHandler where E : Entity where Request : MessageObject, ILocationRequest where Response : MessageObject, ILocationResponse
  35. {
  36. protected abstract ETTask Run(E unit, Request request, Response response);
  37. public async ETTask Handle(Entity entity, Address fromAddress, MessageObject actorMessage)
  38. {
  39. try
  40. {
  41. Fiber fiber = entity.Fiber();
  42. if (actorMessage is not Request request)
  43. {
  44. Log.Error($"消息类型转换错误: {actorMessage.GetType().FullName} to {typeof (Request).Name}");
  45. return;
  46. }
  47. if (entity is not E ee)
  48. {
  49. Log.Error($"Actor类型转换错误: {entity.GetType().FullName} to {typeof (E).FullName} --{typeof (Request).FullName}");
  50. return;
  51. }
  52. int rpcId = request.RpcId;
  53. Response response = ObjectPool.Fetch<Response>();
  54. try
  55. {
  56. await this.Run(ee, request, response);
  57. }
  58. catch (RpcException exception)
  59. {
  60. response.Error = exception.Error;
  61. response.Message = exception.ToString();
  62. }
  63. catch (Exception exception)
  64. {
  65. response.Error = ErrorCode.ERR_RpcFail;
  66. response.Message = exception.ToString();
  67. }
  68. response.RpcId = rpcId;
  69. // 这里是为了保证response消息在handler消息处理完成之后发出,
  70. // 因为MessageLocationSenderComponentSystem里面的Send方法有可能需要从location获取actorid
  71. // 这样会导致send实际上进入了新的协程,从而response却先发送出去了
  72. using (await fiber.Root.GetComponent<CoroutineLockComponent>().Wait(CoroutineLockType.MessageLocationSender, entity.Id))
  73. {
  74. fiber.Root.GetComponent<ProcessInnerSender>().Reply(fromAddress, response);
  75. }
  76. }
  77. catch (Exception e)
  78. {
  79. throw new Exception($"解释消息失败: {actorMessage.GetType().FullName}", e);
  80. }
  81. }
  82. public Type GetRequestType()
  83. {
  84. return typeof (Request);
  85. }
  86. public Type GetResponseType()
  87. {
  88. return typeof (Response);
  89. }
  90. }
  91. }