ET框架关于opCode的理解

80 篇文章 5 订阅
  • 因为所有的网络消息在发送时候格式都是这样
    在这里插入图片描述
  • 对于用Protobuf定义的每一消息类型class,都需要定义一个对应消息头code
  • 在发送的时候,先将消息体进行序列化,再将code进行序列化,进行组装发送
 //这个代码没有进行过优化,会产生严重GC,不要复制使用。这里只是作为演示
	static byte[] PackMsg(IMessage msg)
		{
			byteCollection.Clear();
			var code = Dispatch.GetOpCode(msg.GetType());
			byteCollection.AddRange(BitConverter.GetBytes(code));
			byteCollection.AddRange(msg.ToByteArray());
			return byteCollection.ToArray();
		}
  • 我这里使用的code是ushort类型,只占用两个字节,用BitConverter可以方便转换
问题
  • 产生问题在于,protobuf是先定义.proto文件,然后根据这个文件来生成.cs文件
  • 如果直接在生成的.cs文件里面给每个消息类标记Message[Opcode.Login]会产生问题
  • 就是每次修改.proto文件重新生成的时候,会导致标记的opCode被覆盖。
    在这里插入图片描述
  • 但是还好他生成是分部类,ET框架就利用这点把消息类分成两部分,一部分是消息体,一部分是定义opCode和自己的接口这些
    在这里插入图片描述
  • 但是我比较懒,我不想写那么多。直接通过反射获取所有类型,并且按照遍历顺序给每一个打一个ID就是了
  • 客户端和服务端使用同一个程序集,所以序号也是一样的。
  • 但是潜在的问题是
  • 1.必须把客户端和服务端的消息类型定义在一起
static void GetAllMessageType()
		{
			var assembly = Assembly.GetExecutingAssembly();
			//注意这里标记开始code
			ushort startIndex = 1;
			foreach (var type in assembly.GetTypes())
			{
				if (type.Namespace == nameof(Message) && type.GetInterface(nameof(IMessage)) != null)
				{
					msgTable.Add(startIndex, type);
					msgInstanceTable.Add(startIndex, (IMessage)Activator.CreateInstance(type));
					startIndex++;
				}
			}
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值