ET---Session3.0学习笔记(与2.0的差异)

Session3.0学习笔记(与2.0的差异)

请大家关注我的微博:@NormanLin_BadPixel坏像素


这里是2.0的传送门


首先我们看到,与2.0相比,多了AwakeStart的注册。虽然AWakeSystemStartSystem也是3.0新加的,不过我们不难猜出来,这个跟之前的Event应该差不多。

private readonly Dictionary<uint, Action<PacketInfo>> requestCallback = new Dictionary<uint, Action<PacketInfo>>();

private readonly byte[] flagBytes = new byte[1];
private readonly List<byte[]> byteses = new List<byte[]>() {new byte[0], new byte[0], new byte[0]};
private readonly List<byte[]> rpcByteses = new List<byte[]>() { new byte[0], new byte[0], new byte[0], new byte[0] };

而且,requestCallback里面的回调函数也不再是传入object参数而是PacketInfo,比较短所以我就直接贴出来了。

public struct PacketInfo
{
    public ushort Opcode;
    public uint RpcId;
    public byte[] Bytes;
    public ushort Index;
    public ushort Length;
}

多了一个存放flag的变量。

byteses多了一块数据并且多了存放RPC消息的rpcByteses

这里我们不难猜出,多出来的这一块数据应该就是用来存放flag的了。

我们具体来看Run方法。

private void Run(Packet packet)
{
    if (packet.Length < Packet.MinSize)
    {
        Log.Error($"message error length < {Packet.MinSize}, ip: {this.RemoteAddress}");
        this.Network.Remove(this.Id);
        return;
    }

    byte flag = packet.Flag();
    ushort opcode = packet.Opcode();
    PacketInfo packetInfo = new PacketInfo
    {
        Opcode = opcode,
        Bytes = packet.Bytes
    };

    if ((flag & 0xC0) > 0)
    {
        uint rpcId = packet.RpcId();
        packetInfo.RpcId = rpcId;
        packetInfo.Index = Packet.RpcIdIndex + 4;
        packetInfo.Length = (ushort)(packet.Length - packetInfo.Index);

        // flag第2位表示这是rpc返回消息
        if ((flag & 0x40) > 0)
        {
            Action<PacketInfo> action;
            if (!this.requestCallback.TryGetValue(rpcId, out action))
            {
                return;
            }
            this.requestCallback.Remove(rpcId);

            action(packetInfo);
            return;
        }
    }
    else
    {
        packetInfo.RpcId = 0;
        packetInfo.Index = Packet.RpcIdIndex;
        packetInfo.Length = (ushort)(packet.Length - packetInfo.Index);
    }

    this.Network.MessageDispatcher.Dispatch(this, packetInfo);
}

我们发现Run方法已经大变样了。首先取消了数据压缩,然后多了对Flag的判断。这里我们就可以知道,原来Packet里面的Flag标识的是是否是Rpc消息。

从作者的注释看来,Flag占1个字节 = 8位。我们用8位中的前两位来区分Rpc消息,如果前两位中至少有一位是1,则它是Rpc消息。在此基础上,如果第二位是1,则它是Rpc返回的消息,否则,它是Rpc请求的消息。

对这些消息的处理,代码里写的很清楚。我们疑惑的是,为什么

packetInfo.Index = Packet.RpcIdIndex + 4;

这可能关系到Rpc消息的组成结构,等我们之后遇到的时候再说吧。

之后的几个Call都跟2.0的很类似,不过多了Flag的设置,0x80 = 1000 0000

这里说明一下作者注释的内容。

// 抛到外层不能再使用之前的byte[],因为那是Packet所有的,为了减少gc一直传到这个位置
byte[] newBytes = new byte[packetInfo.Length + packetInfo.Index];
Array.Copy(packetInfo.Bytes, 0, newBytes, 0, newBytes.Length);
packetInfo.Bytes = newBytes;

看过2.0的应该知道,2.0中的PacketParser获取数据会重新new一个Byte[],相当于获取到了一个副本,而3.0则是直接获取Packet中的数据引用。这样做是为了减少GC,但是在这个地方,我们需要Packet数据的副本,所以我们得经过这个步骤。我也不知道这两者到底哪个好,不过作者既然更新成了这种方式,必然有他的道理。但是我们也抱有疑惑,希望大佬能为我们解答,到底是在获取数据的时候创建一个副本好,还是在需要副本的时候经过这一系列的操作好? 如果能讲讲为什么那就更好了。

关于Replay方法,因为是对Rpc消息的回复,所以的设置Flag = 0x40 = 0100 0000

之后的SendMessage就很好理解了。

结束语

学而时习之——————Norman林

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值