MsgReceiver.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System;
  2. namespace XGame.Framework.Network
  3. {
  4. internal class MsgReceiver : IMsgReceiver
  5. {
  6. private IMsgReceiverListener _listener;
  7. private ISessionContext _context;
  8. public MsgReceiver(IMsgReceiverListener listener, ISessionContext context)
  9. {
  10. _listener = listener;
  11. _context = context;
  12. }
  13. //response 12
  14. //|<- Head ->|<- Body ->|
  15. //| magic | type | compress | encryption |0000| seqID | protoId| msglength| msg |
  16. //| 1byte | 2bit | 1bit | 1bit |4bit| 4byte | 4byte | 2byte | Nbyte |
  17. //| 0 | 1 | 2 3 4 5 | 6789 | 10 11 | |
  18. //push 8
  19. //|<- Head ->|<- Body ->|
  20. //| magic | type | compress | encryption |0000| protoId| msglength| msg |
  21. //| 1byte | 2bit | 1bit | 1bit |4bit| 4byte | 2byte | Nbyte |
  22. //| 0 | 1 | 2345 | 6 7 | |
  23. public void Receive(byte[] bytes, int headLen, int msgLen)
  24. {
  25. int type = bytes[1] >> 6;
  26. int compress = bytes[1] >> 5 & 0x1;
  27. int encryption = bytes[1] >> 4 & 0x1;
  28. int protoID = -1;
  29. int seqID = -1;
  30. NetLog.LogHexString($"[Net] headLen:{headLen} msgLen:{msgLen}\n解析前:", bytes, headLen, msgLen);
  31. if (bytes[0] != NetDefine.MAGIC)
  32. {
  33. Log.Error($"[Net] 协议版本错误. bytes:{bytes[0]} magic:{NetDefine.MAGIC}");
  34. return;
  35. }
  36. if (type != (int)MsgType.REQUEST)
  37. { //收到任何消息都算收到心跳应答
  38. _listener?.OnHeartbeatReceived();
  39. }
  40. switch ((MsgType)type)
  41. {
  42. case MsgType.HEART_BEAT:
  43. NetLog.LogVerbose("[Net] 收到心跳应答消息.");
  44. return;
  45. case MsgType.RESPONSE:
  46. seqID = (bytes[2] << 24) + (bytes[3] << 16) + (bytes[4] << 8) + (bytes[5]);
  47. protoID = (bytes[6] << 24) + (bytes[7] << 16) + (bytes[8] << 8) + (bytes[9]);
  48. NetLog.LogVerbose($"[Net] [Response] protoid:{protoID} seqID:{seqID}");
  49. if (seqID <= -1)
  50. {
  51. Log.Error(string.Format("[Net] seq:{0} HeadLen:{1} MsgLen:{2} 抛弃一条非客户端请求,服务端私自发送来的消息", seqID, headLen, msgLen));
  52. return;
  53. }
  54. break;
  55. case MsgType.PUSH:
  56. protoID = (bytes[2] << 24) + (bytes[3] << 16) + (bytes[4] << 8) + (bytes[5]);
  57. NetLog.LogVerbose($"[Net] [Push] protoid:{protoID}");
  58. break;
  59. default:
  60. Log.Error($"[Net] MsgType未知的一条消息 type:{type}");
  61. return;
  62. }
  63. //做解密
  64. if (encryption == 1)
  65. {
  66. try
  67. {
  68. _context.Encryptor.Decrypt(ref bytes, ref headLen, ref msgLen);
  69. NetLog.LogHexString($"[Net] type:{(MsgType)type} protoid:{protoID} seq:{seqID}\n<<<<<解密后>>>>>:", bytes, headLen, msgLen);
  70. }
  71. catch (Exception e)
  72. {
  73. Log.Exception($"[Net] 解密 msg {protoID} 出错\n", e);
  74. return;
  75. }
  76. }
  77. //做解压
  78. if (compress == 1)
  79. {
  80. try
  81. {
  82. _context.Compressor.Decompress(ref bytes, ref headLen, ref msgLen);//新的buffer
  83. NetLog.LogHexString($"[Net] type:{(MsgType)type} protoid:{protoID} seq:{seqID}\n■■■■■解压后■■■■■:", bytes, headLen, msgLen);
  84. }
  85. catch (Exception e)
  86. {
  87. Log.Exception($"[Net] 解压 msg {protoID} 出错\n", e);
  88. return;
  89. }
  90. }
  91. IMessage msg = null;// = _context.Generator.GetMessage(protoID);
  92. if (msgLen != 0)
  93. {
  94. _context.Serializer.Read(bytes, headLen, msgLen + headLen, protoID, out msg);
  95. }
  96. if (msg != null)
  97. {
  98. //if (msgLen != 0)
  99. //{
  100. // try
  101. // {
  102. // msg.ParseFrom(bytes, headLen, msgLen + headLen);
  103. // NetLog.LogVerbose($"[MsgReceiver] type:{(MsgType)type} protoid:{protoID} seq:{seqID}\n解析后:[{msg.GetType().Name}]{XJson.ToJson(msg)}");
  104. // }
  105. // catch (Exception e)
  106. // {
  107. // Log.Exception($"[Session] 解析 msg {protoID} Excep出错 可能是双端proto文件没有同步 还有可能是本服跨服proto不一致\n", e);
  108. // return;
  109. // }
  110. //}
  111. msg.InstanceID = seqID;
  112. if (msg.ProtocolID == NetDefine.CONN_PROTO_ID && msg.InstanceID == NetDefine.CONN_SEQ_ID)
  113. {
  114. NetLog.LogVerbose($"[Net] type:{(MsgType)type} protoid:{protoID} seq:{seqID} process immediately!!!");
  115. _context.Processer.Process(msg);//对握手这条立即处理。
  116. }
  117. else
  118. {
  119. //var data = SessionThreadData.Acquire();
  120. //data.EventType = type == (int)MsgType.PUSH ? ESessionCode.ProcessPush : ESessionCode.ProcessResponse;
  121. //data.Context = msg;
  122. NetLog.LogVerbose($"[Net] type:{(MsgType)type} protoid:{protoID} seq:{seqID} Enqueue wait to process");
  123. _context.Synchronizer.Enqueue(msg);
  124. }
  125. }
  126. else
  127. {
  128. Log.Error($"[Net] protoid : {protoID} 取不到IMessage,可能是proto文件没有生成");
  129. }
  130. }
  131. }
  132. }