MessageDispatherComponent学习笔记

MessageDispatherComponent

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


Demo3.0发布后,对MessageDispatherComponent进行了更新,变化其实不大,只是把HotFix相关的代码移除了,大家自己看一下就好。
2018/4/11

MessageDispatherComponent实例分析在另外一个笔记里,有兴趣的可以在看完后到 这里 看一下。里面也解释了iMHandler接口的作用。


同样的猜猜先。
“消息调度”。
我之前也学过一点skynet,并且写了一个简单的文档sample gate框架启动流程,所以我大概能猜到这个“消息调度”是干啥的。这里给没了解的同学说一下我自己的理解。

消息调度,调度的是什么消息,又是怎么调度的?其实只要清楚这些,消息调度的作用就很好理解了。

首先,调度的是什么消息。调度的是从网络传过来的数据,服务端就是调度从客户端传过来的消息,客户端则是调度从服务端传过来的消息。

(以帧同步为例)
怎么调度的呢?我们想象一下,我们在客户端上操作,都希望传一些什么数据给服务端呢?大致分一下,1:角色移动。2.角色攻击。就先举这两种数据吧。当我们在客户端这边操作了角色移动和攻击。这时会产生两条指令,msg1和msg2,msg1的type是move,msg2的type是attack,里面的具体信息我们先不用管。这个时候,我们要把这些数据传给服务端。这个时候,消息调度器的第一个作用就出来了,它会把这些信息给统一打包,然后通过自定义的数据类型,把这些信息序列化成json或者protobuff或其他的一些数据,方便网络传输。打好包后,再发送给服务端。

而服务端接收到这些数据,会解析这些数据,这个时候,消息调度器的第二个作用体现出来了,它会用和客户端规定好的数据类型,把序列化的数据再反序列化成对象。然后对这些对象进行一些我们还不知道的处理,比如压入对应的帧队列。同样的,服务端会把当前帧的指令集合发送给客户端,发送的原理跟客户端差不多。而客户端接收到这些消息,同样的会把这些数据反序列化成对象,然后利用消息调度器对消息进行分发处理,这就是消息调度器的第三个作用。比如我们的客户端接收到了自己发送给服务端然后又传回来的msg1和msg2,这个时候,消息调度器会根据msg的type把这些消息交给不同的处理器处理。比如会把type为move的信息交给角色移动组件处理,而把type为attack的消息交给角色攻击组件处理,具体怎么处理就是不同组件需要干的,消息调度器只是起到了一个调度的作用。
(这里的理解是我根据skynet猜的,ET里面的具体是什么作用我们还是得看代码)

看代码

private Dictionary<ushort, List<IMessageMethod>> handlers;

IMessageMethod

void Run(AMessage a);

AMessage

空的类,但是有很多的子类。现在我们不管。

MessageDispatherComponent

foreach (Type type in types)
{
    object[] attrs = type.GetCustomAttributes(typeof(MessageHandlerAttribute), false);
    if (attrs.Length == 0)
    {
        continue;
    }
    MessageHandlerAttribute messageHandlerAttribute = (MessageHandlerAttribute)attrs[0];
    IMHandler iMHandler = (IMHandler)Activator.CreateInstance(type);
    if (!this.handlers.ContainsKey(messageHandlerAttribute.Opcode))
    {
        this.handlers.Add(messageHandlerAttribute.Opcode, new List<IMessageMethod>());
    }
    this.handlers[messageHandlerAttribute.Opcode].Add(new IMessageMonoMethod(iMHandler));
}

这段代码跟之前的EventComponent也很像,无非就是把拥有MessageHandler特性的类向消息调度器注册对应的处理器。因为这个Demo是含热更新的,所以应该有很多脚本是写在热更新层的,所以我们不能通过Shift+F12快速的找到具体都有哪些类拥有MessageHandler特性。那这里也就深究下去了,我们了解一下思路。

public void Handle(MessageInfo messageInfo)
{
    List<IMessageMethod> actions;
    if (!this.handlers.TryGetValue(messageInfo.Opcode, out actions))
    {
        Log.Error($"消息 {Opcode2Name.GetName(messageInfo.Opcode)}({messageInfo.Opcode}) 没有处理");
        return;
    }

    foreach (IMessageMethod ev in actions)
    {
        try
        {
            ev.Run(messageInfo.Message);
        }
        catch (Exception e)
        {
            Log.Error(e.ToString());
        }
    }
}

瞧,这就是接收到消息后,根据消息的操作符(类型,比如之前说的Move或者Attack)分配给不同的处理器。

MessageInfo

public ushort Opcode { get; set; }
public AMessage Message { get; set; }

public MessageInfo(ushort opcode, AMessage message)
{
    this.Opcode = opcode;
    this.Message = message;
}

现在终于懂得了,之前说的Opcode就是用来区别不同操作的消息。而不同操作类型的消息里面包含的消息内容肯定也是不一样的,那就是AMessage的派生类需要考虑的咯。

不过这里的消息调度并没有我开头提到的对数据的序列化打包操作,这个操作可能被作者分到其他模块去了吧。

结束语

之前学的东西不见的没用 ———–NormanLin

书到用时方恨少

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值