MsgSender.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using XGame.Framework.Interfaces;
  3. namespace XGame.Framework.Network
  4. {
  5. internal class MsgSender : IMsgSender, IReset
  6. {
  7. private ISessionContext _context;
  8. private int seqID = -1;
  9. /// <summary>
  10. /// 消息间隔,默认3秒
  11. /// </summary>
  12. private const int _interval = 3000;
  13. private long _lastTime = 0;
  14. private int _lastID = -1;
  15. public MsgSender(ISessionContext context)
  16. {
  17. _context = context;
  18. }
  19. public bool IsCanSend(IMessage message, bool useFilter)
  20. {
  21. if (useFilter)
  22. {
  23. var nowTime = _context.Time.GetNowTime();
  24. if (_lastTime == 0 || nowTime - _lastTime > _interval)
  25. { // 没记录时间 或 已经超时, 刷新时间
  26. _lastTime = nowTime;
  27. }
  28. else
  29. {
  30. return false;
  31. }
  32. }
  33. message.InstanceID = ++seqID;
  34. if (useFilter)
  35. {
  36. _lastID = message.InstanceID;
  37. }
  38. return true;
  39. }
  40. //|<- Head ->|<- Body ->|
  41. //| magic | type | compress | encryption |0000| seqID | protoId| msglength| msg |
  42. //| 1byte | 2bit | 1bit | 1bit |4bit| 4byte | 4byte | 2byte | Nbyte |
  43. //| 0 | 1 | 2 3 4 5 | 6789 | 10 11 | |
  44. public ESessionCode Send(IMessage message, bool openEncrypt)
  45. {
  46. _context.Serializer.Write(message, out var bytes, out var msgOffset, out var msgLength);
  47. //magic
  48. bytes[0] = NetDefine.MAGIC;
  49. //type compress
  50. int type = (int)MsgType.REQUEST << 6;
  51. bool isCompress = (msgLength + NetDefine.HEAD_LENGTH_REQUEST) > NetDefine.CompressThreshold;
  52. int compress = (isCompress ? 1 : 0) << 5;
  53. int encryption = (openEncrypt ? 1 : 0) << 4;
  54. bytes[1] = Convert.ToByte((compress + type + encryption) & 0xFF);
  55. //seqID
  56. bytes[2] = Convert.ToByte(message.InstanceID >> 24 & 0xFF);
  57. bytes[3] = Convert.ToByte(message.InstanceID >> 16 & 0xFF);
  58. bytes[4] = Convert.ToByte(message.InstanceID >> 8 & 0xFF);
  59. bytes[5] = Convert.ToByte(message.InstanceID & 0xFF);
  60. //protoID
  61. bytes[6] = Convert.ToByte(message.ProtocolID >> 24 & 0xFF);
  62. bytes[7] = Convert.ToByte(message.ProtocolID >> 16 & 0xFF);
  63. bytes[8] = Convert.ToByte(message.ProtocolID >> 8 & 0xFF);
  64. bytes[9] = Convert.ToByte(message.ProtocolID & 0xFF);
  65. if (isCompress)
  66. {
  67. _context.Compressor.Compress(ref bytes, ref msgOffset, ref msgLength);
  68. }
  69. if (openEncrypt)//rc4的话 用新数组进行保存
  70. {
  71. _context.Encryptor.Encrypt(ref bytes, ref msgOffset, ref msgLength);
  72. }
  73. //msglengh
  74. bytes[10] = Convert.ToByte(msgLength >> 8 & 0xFF);
  75. bytes[11] = Convert.ToByte(msgLength & 0xFF);
  76. NetLog.LogHexString($"发送消息", bytes, 0, msgLength + NetDefine.HEAD_LENGTH_REQUEST);
  77. var result = _context.Session.Send(bytes, 0, msgLength + NetDefine.HEAD_LENGTH_REQUEST);
  78. return result ? ESessionCode.None : ESessionCode.SendFailed;
  79. }
  80. public void Reset()
  81. {
  82. seqID = -1;
  83. _lastID = -1;
  84. _lastTime = 0;
  85. }
  86. public bool VerifyInstanceID(int instanceID)
  87. {
  88. if (_lastID == instanceID)
  89. {
  90. _lastTime = 0;
  91. return true;
  92. }
  93. return false;
  94. }
  95. //private bool CanSendMsg(IMessage msg)
  96. //{
  97. // if (!_sessionNode.MsgContext.CanSend)//false request 和 response 没有对应
  98. // {
  99. // Log.Debug(string.Format("[Session Send Filter] <{0}> {1} lastSeq: {2} \n消息发送过快,上条消息尚未回复导致消息被过滤,请重发或使用INetModule.Send(string sessionType, IMessage msg, bool isFilter),isFilter设置为false\n{3}", msg.ProtocolID, msg.GetType().Name, _sessionNode.MsgContext.LastID, XJson.ToJson(msg)));
  100. // var args = ObjectPool.Acquire<SessionMsgFilterEventArgs>();
  101. // args.Message = msg;
  102. // _sessionNode.Notify(EventDefine.SESSION_MSG_FILTER, args);
  103. // ObjectPool.Recycle(args);
  104. // return false;
  105. // }
  106. // _sessionNode.MsgContext.CanSend = false;
  107. // //计时开始
  108. // _timer?.Cancel();
  109. // _timer = _timeModule.AddDelayTimer(_interval, Timeout);
  110. // return true;
  111. //}
  112. //private void DebugMessage(IMessage message)
  113. //{
  114. // if (_sessionNode.bDebug)
  115. // {
  116. // Log.Info("[Session] Send <{1}> {2}: Seq:{4} Timestamp:{0}\n{3}",
  117. // _timeModule.GetNowTime(ClockType.Client), message.ProtocolID, message.GetType().Name, XJson.ToJson(message), message.InstanceID);
  118. // }
  119. //}
  120. //private void SendFail(IMessage message)
  121. //{
  122. // var args = ObjectPool.Acquire<SessionCantSendEventEventArgs>();
  123. // args.message = message;
  124. // if (_sessionNode.bDebug)
  125. // {
  126. // Log.Error("[Session Send Fail] Send <{1}> {2}: Timestamp:{0}\n{3}",
  127. // _timeModule.GetNowTime(ClockType.Client), message.ProtocolID, message.GetType().Name, XJson.ToJson(message));
  128. // }
  129. // _sessionNode.Notify(EventDefine.SESSION_CANT_SEND, args);
  130. // ObjectPool.Recycle(args);
  131. //}
  132. //private void SendEvent(IMessage msg, bool isFilter)
  133. //{
  134. // var args = ObjectPool.Acquire<SessionRequestSentEventArgs>();
  135. // args.protocolID = msg.ProtocolID;
  136. // args.context = msg.Context;
  137. // args.IsFilter = isFilter;
  138. // args.RequestMsg = msg;
  139. // args.seq = msg.InstanceID;
  140. // _sessionNode.Notify(EventDefine.SESSION_REQUEST_SENT, args);
  141. // ObjectPool.Recycle(args);
  142. //}
  143. }
  144. }