根据ET5文档介绍,MailBoxComponent组件一般与Actor搭配使用,挂载该组件后,就可以通过Actor发送消息。

官方demo主要有两种使用方式:

session.AddComponent<MailBoxComponent, string>(MailboxType.GateSession);
await unit.AddComponent<MailBoxComponent>().AddLocation();
await unit.AddComponent<MailBoxComponent>()

1、这里拆分一下服务端的实体(客户端):
  玩家在客户端有Player和Unit:Player有id,只有一个自己。Unit会有多个,自己和其他人。
  玩家在服务端:
    Realm:只负责注册,查询和验证等功能,不会有长链接的相关处理
    Gate:在网关上有Player实体:有IId,Account和UnitId--关联Map服的Unit实体。Player绑定了Session。
    Map:玩家在Map服务器上有Unit实体有唯一ID,挂载UnitGateComponent组件关联GateSessionId。

2、客户端,各服务器都是不同的端,都不在一台设备上。只是用相同的UnitID,分别在这些端创建Player和Unit实例,实例上存着需要的id号来识别谁是谁和找到连接session。
session就是在不同端建立的持续通信的连接。

Client与Gate通信,网关上存着Player绑定了session,有UnitID就能找到连接session进行通信。

服务端之间,你可以在每个服务端定义一个构建和获取与其它服务端的连接session的方法。

非网关服务器=》客户端,可以用ActorId,构建ActorMessageSender通信。

3、举例看看

在InnerMessageDispatcher中添加注释,方便查看内网中的Actor消息传递

HandleIActorMessage函数中:Log.Info("InnerMessageDispatcher内网消息转发:" + message.ActorId + "---" + entity);
 

  

 3.1:Gate服务器不处理消息,直接转发消息

      注意:C2G_LoginGateHandler中 session.AddComponent<MailBoxComponent, string>(MailboxType.GateSession);当其他服务器消息发送到Gate的Session上时,消息会自动转发给前端,Gate服务器不会有相应的Handler处理该信息。

  1、先注释寻路消息:G2M_CreateUnitHandler 中注释掉  await unit.AddComponent<MailBoxComponent>().AddLocation();

编译运行,

参考前端,有小人出现。说明创建小人消息发送到了前端,

  3.2:Gate服务器处理消息--不直接转发。

     1、调整代码 C2G_LoginGateHandler ,给Player添加个MailBox组件。

            Player player = ComponentFactory.Create<Player, string>(account);
player.AddComponent<MailBoxComponent>(); //新加入的代码 Game.Scene.GetComponent<PlayerComponent>().Add(player);
session.AddComponent<SessionPlayerComponent>().Player = player;
session.AddComponent<MailBoxComponent, string>(MailboxType.GateSession);

 2、在Gate服务器中添加一个消息处理Handler

using System.Threading.Tasks;
using ETModel; namespace ETHotfix
{
[ActorMessageHandler(AppType.Gate)]
public class Actor_MatchSucess_NttHandler: AMActorHandler<Player, Actor_MatchSucess_Ntt>
{
protected override async ETTask Run(Player entity, Actor_MatchSucess_Ntt message)
{
Log.Info($"-------收到Map服务器发送的Actor消息---玩家{entity.Id}收到消息---:" + message.GamerID);
await Task.CompletedTask;
}
}
}
3、在内网中添加信息 InnerMessage.proto
在InnerMessage.proto中添加

message Actor_MatchSucess_Ntt // IActorMessage
{
int32 RpcId = 90;
int64 ActorId = 94;
int64 GamerID = 1;
}

4、在Map中向Gate的Player中发送消息。G2M_CreateUnitHandler 中添加代码。

注意:这个添加的代码,ActorMessageSender 发送消息时往Player中发送,不是Session中。

            await unit.AddComponent<MailBoxComponent>().AddLocation();
unit.AddComponent<UnitGateComponent, long>(request.GateSessionId);
Game.Scene.GetComponent<UnitComponent>().Add(unit);
response.UnitId = unit.Id; /**********添加测试代码 ********/
//测试给Gate服务器发送Actor消息
// 注意,Gate中Player必须 await player.AddComponent<MailBoxComponent>().AddLocation();
ActorMessageSenderComponent actorLocationSenderComponent = Game.Scene.GetComponent<ActorMessageSenderComponent>();
//这里是发送到Session实体,会直接转发到前端--需要调整Actor_MatchSucess_Ntt,OuterMessage.proto中添加消息体
// ActorMessageSender actorMessageSender = actorLocationSenderComponent.Get(request.GateSessionId);
//这里是发送到Player,Gate有相关Handler处理,不会直接转发
ActorMessageSender actorMessageSender = actorLocationSenderComponent.Get(request.PlayerId);
actorMessageSender.Send(new Actor_MatchSucess_Ntt(){GamerID = 32435});
/**********添加测试代码 ********/
5、编辑运行

4、总结

  同样是Actor消息,有的是发送给Gate,有的是发送给前端。其实都是发送给了Gate,当信息发送给Session时,Gate会直接转发给前端,因为Session挂载MailBox时添加了MailBoxType.GateSession类型,使用会直接转发。Player挂载MailBox时,没有加类型,使用会转发到相关Handler里进行处理。

  至于Player挂载MailBox两种方式  player.AddComponent<MailBoxComponent>(); 和 await player.AddComponent<MailBoxComponent>().AddLocation();  个人理解:后面加AddLocation,会将实体加入到Location服务器中,方便发送 IActorLocationMessage 这种带 Location的消息--这种消息可能会在Location服务器中查询用户。

  所以不论多少个端,Client,Gate,Map,Realm,只是在每个端都创建了同样UnitId的Player实例,和用同样UnitD创建的Unit实例,每一个玩家就像在每个端都有分身或影子,玩家的分身之间把消息传来传去,改变着玩家的状态。

  另外,各类服务器(主要指map)也可以通过网关上客户端与网关的session连接,给一群玩家的本尊客户端广播消息。

  注:Realm只需要认证账号,不需要分身

  Demo中的这几大实例id,就是几种实体(Entity)的InstanceId

    Player,Session,Unit

    • actorsender在构建时,传入一个实体的实例id,就可以给这个实体的实例发消息,不论他在哪个服务器。--例子中player加MailBox
    • 只要有session,player,unit 的实例id就能给他们发actor消息。
    • 而通过session的实例id给用户的网关session发actor消息,session会给你转发给客户端(用户的网关sesion正是网关与客户端的连接session)。

参考内容:https://www.taikr.com/course/1053/task/30966/show

https://github.com/egametang/ET/blob/master/Book/5.4Actor%E6%A8%A1%E5%9E%8B.md

https://www.lfzxb.top/etbook/#54-actor%E6%A8%A1%E5%9E%8B

 

 

ET5 MailBoxComponent 简单介绍的更多相关文章

  1. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  2. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  3. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  4. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  5. angular1.x的简单介绍(二)

    首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...

  6. Linux的简单介绍和常用命令的介绍

    Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...

  7. iOS-iOS开发简单介绍

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...

  8. iOS开发多线程篇—多线程简单介绍

    iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...

  9. iOS开发UI篇—UITabBarController简单介绍

    iOS开发UI篇—UITabBarController简单介绍 一.简单介绍 UITabBarController和UINavigationController类似,UITabBarControlle ...

  10. Android开发自学笔记(Android Studio)—4.界面编程与View组件简单介绍

    一.引言 Android应用开发最重要的一份内容就是界面的开发,无论你程序包含的内容多么优秀,如若没有一个良好的用户交互界面,最终也只是会被用户所遗弃.Android SDK提供了大量功能丰富的UI组 ...

随机推荐

  1. How to grow old

    An individual human existence should be like a river-small at first,narrowly contained within its ba ...

  2. frxpngimage单元的编译错误:frxpngimage left side cannot be assigned to

    一个老项目中,使用软数字录入数据,编译时出现n个:frxpngimage left side cannot be assigned to 原因是使用了frxpngimage单元,在D11中编译出现若干 ...

  3. Greenplum数据库索引解析

    以下是对greenplum数据库使用总结. 创建索引 CREATE INDEX i_test_tb_state_az ON test_tb(name_en) WHERE name_en = 'AZ'; ...

  4. 记一次 .NET某固高运动卡测试 卡慢分析

    一:背景 1. 讲故事 年前有位朋友找到我,说他们的程序会偶发性卡慢 10s 钟,在某些组合下会正常,某些组合下就会出现问题,解释不了其中的原因,让我帮忙看下怎么回事?截图如下: private vo ...

  5. 适用于LixtBox的,开启UI虚拟化时,某些时候需要定位到还没加载的项,比如自动选中某项,视图自动移过去等等

    1 /// <summary> 2 /// 将指定父级的下级索引元素,显示在视野下,使其可见 3 /// </summary> 4 /// <param name=&qu ...

  6. CF1424G题解

    思路 这个题意思很显然,是求 nnn 个区间重叠最多的地方和值. 那么我们能想到用差分数组,在扫一遍的过程中维护最大值和 pospospos. 但是需要注意的是,区间最大会到 10910^9109,直 ...

  7. C#高性能开发之类型系统:从C# 7.0 到C# 14的类型系统演进全景

    自C# 7.0以来,C#语言在类型系统方面引入了众多新数据类型.类型构造和语言特性,以提升性能.类型安全性和开发效率.本文全面整理了从C# 7.0到C# 14.0(截至2025年4月,C# 14.0为 ...

  8. Asp.net core 少走弯路系列教程(七)WebApi 学习

    前言 新人学习成本很高,网络上太多的名词和框架,全部学习会浪费大量的时间和精力. 新手缺乏学习内容的辨别能力,本系列文章为新手过滤掉不适合的学习内容(比如多线程等等),让新手少走弯路直通罗马. 作者认 ...

  9. C#/.NET/.NET Core技术前沿周刊 | 第 36 期(2025年4.21-4.27)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  10. 89.4K star!这个开源LLM应用开发平台,让你轻松构建AI工作流!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 Dify 是一款开源的 LLM 应用开发平台,通过直观的可视化界面整合 AI 工作流.RAG ...