ET框架笔记 (笑览世界写)(转) - &大飞

时间:2024-03-08 08:01:40

ET框架笔记 (笑览世界写)(转)

客户端

1.使用unity2017.2.0版本及以上2018版以下,编译原始版ET客户端报没有引用错误时,删除hoxfit下引用的UnityEngine.dll和UnityEngine.UI.dll,重新引用…\Editor\Data\UnityExtensions\Unity\GUISystem文件下的unityfengine.UI.dll和引用…\Editor\Data\Managed\UnityEngine 文件下的UnityEngine.dll和UnityEngine.CoreModel.dll,注意UnityEngine.dll和UnityEngine.CoreModel.dll必须都为…\Editor\Data\Managed\UnityEngine 文件内的,不然会报错

2.使用2018版本,同上另外需要重新引用项目Assembly-CSharp.dll和Assembly-CSharp-firstpass.dll即ET的Unity项目dll和ET的Unity.Plugins的dll,删除所有失效的dll,不然编译报错需引用Assembly-CSharp.dll和Assembly-CSharp-firstpass.dll。另外安卓SDK别更新最新的Android SDK Build-tools 28rc1工具。

3.unity2017.2.0版本及以上,你还可能用到的类库为:UnityEngine.PhysicsModule.dll,若出现如下截图错误,可在如下文件夹目录下引用它…\Editor\Data\Managed\UnityEngine ,根据实际情况添加,也可能会出现其它报错,需要引用对应的dll,当然不怕麻烦或者为了不报类似错可以把如下文件夹目录…\Editor\Data\Managed\UnityEngine下的所有dll全部引用。2017.2.0及以上的版本把unity的dll按系统分类拆分成很多个,所以需要分别引用需要的dll。

引用

4.如果Hotfix报关于UI的Canvas的错,需要在Hotfix中添加UnityEngine.UIModule.dll。

UIModule报错

5.(可选)使用unity2017.2.0以下版本,编译原始版ET客户端报没有引用错误时,删除hoxfit下引用的UnityEngine.dll和UnityEngine.UI.dll,重新引用…\Editor\Data\UnityExtensions\Unity\GUISystem文件下的unityengine.UI.dll和引用…\Editor\Data\Managed 文件下的UnityEngine.dll。

6.Microsoft Visual Studio使用15.5.4以上版本,否则Unity可能会加载不了Hotfix.dll。如果加载不了需要自行重新引用Hotfix.dll。

7.安装VS2017、unity2017及以上版本后,按流程操作无误,可能仍出现问题,可重启计算机试试。

注:

1.在运行和打包时,关闭全局配置界面,避免出现报错干扰。

2.Tool上ILRuntime的生成工具是为了给ILRuntime提速用,需先加上ILRuntime的宏再点击上面的两个按钮,不然会报错或者无法正常生成。

3.在2018中打包需要Api Compatibility Level选择 .NET4.X库,不然会报Bson的错。

客户端修改界面步骤:

调试方法:

1、unity设置标记输入框里的ILRuntime宏删除。

2、在VS里重新生成解决方案

3、工具菜单标记资源包在点PC生成资源包菜单

4、将Release文件夹下的PC文件夹替换掉主工程文件夹(LandlordsCore-master)文件夹下的PC文件夹

5、热更时恢复unity宏标记设置

增加界面:

1.在Global/UI下添加需要增加界面(如:NewUI)的父物体(如:NewUIParent),在UI的ReferenceCollector上添加界面的父物体(NewUIParent)的引用。

2.需要增加的界面(NewUI)添加CanvasConfig并将CanvasName设置为需要增加界面的父物体(NewUIParent)的名字。

3.在UIType枚举里面添加枚举成员(如:BEnum)。

4.模仿UILoginFactory类新建一个UI***Factory类,在界面添加按钮处调用打开方法:Hotfix.Scene.GetComponent<UIComponent>().Create(UIType.BEnum);

5.在新增加的界面(NewUI)做逻辑处理须模仿UILoginComponent类新建一个UI***Component类,在类中实现想要的效果;在新增加的界面(NewUI)的ReferenceCollector组件上需要的引用。

6.热更时须打开unity设置标记输入框里的ILRuntime宏,Hotfix工程添加ILRuntime宏(属性—–>生成–>条件编译符号处加上 ILRuntime,重新生成修改过的工程,如不添加宏会无法启动。

7.点击工具菜单Tools–>打包–>设置标记–>设置标记,再Tools–>打包–>PC生成资源,将Release文件夹下的PC文件夹替换掉主工程文件夹(LandlordsCore-master)文件夹下的PC文件夹。

热更时,只能hotfix拓展Model中的类,model无法拓展hotfix中的类,热更的拓展方法只能放在hotfix中,model中不能调用hotfix中的方法。

服务端(基于哲学棋牌Demo)

各服务器作用

注:按需将整个系统拆分成不同的进程。比如你需要一个单独处理聊天的服务器进程,那么可以增加Chat进程。根据需求配置服务器功能。

1.Manager:连接客户端的外网和连接内部服务器的内网,对服务器进程进行管理,自动检测和启动服务器进程。加载有内网组件NetInnerComponent,外网组件NetOuterComponent,服务器进程管理组件。自动启动突然停止运行的服务器,保证此服务器管理的其它服务器崩溃后能及时自动启动运行。

2.Realm:对ActorMessage消息进行管理(添加、移除、分发等),连接内网和外网,对内网服务器进程进行操作,随机分配Gate服务器地址。加载有ActorMessage消息分发组件ActorMessageDispatherComponent,ActorManager消息管理组件ActorManagerComponent,内网组件NetInnerComponent,外网组件NetOuterComponent,服务器进程管理组件LocationProxyComponent,Gate服务器随机分发组件。客户端登录时连接的第一个服务器,也可称为登录服务器。

3.Gate:对玩家进行管理,对ActorMessage消息进行管理(添加、移除、分发等),连接内网和外网,对内网服务器进程进行操作,随机分配Gate服务器地址,对Actor消息进程进行管理,对玩家ID登录后的Key进行管理。加载有玩家管理组件PlayerComponent,ActorMessage消息分发组件ActorMessageDispatherComponent,ActorManager消息管理组件ActorManagerComponent,内网组件NetInnerComponent,外网组件NetOuterComponent,服务器进程管理组件LocationProxyComponent,Actor消息管理组件ActorProxyComponent,管理登陆时联网的Key组件GateSessionKeyComponent。对客户端的登录信息进行验证和客户端登录后连接的服务器,登录后通过此服务器进行消息互动,也可称为验证服务器。

4.Location:连接内网,服务器进程状态集中管理(Actor消息IP管理服务器)。加载有内网组件NetInnerComponent,服务器消息处理状态存储组件LocationComponent。

5.Map:连接内网,对ActorMessage消息进行管理(添加、移除、分发等),对场景内现在活动物体存储管理,对内网服务器进程进行操作,对Actor消息进程进行管理,对ActorMessage消息进行管理(添加、移除、分发等),服务器帧率管理。ActorMessage消息分发组件ActorMessageDispatherComponent,ActorManager消息管理组件ActorManagerComponent,内网组件NetInnerComponent,服务器进程管理组件LocationProxyComponent,服务器帧率管理组件ServerFrameComponent。

6.AllServer:将以上服务器功能集中合并成一个服务器。另外增加DB连接组件DBComponent,DB管理组件DBProxyComponent。

7.Benchmark:连接内网和测试服务器承受力。加载有内网组件NetInnerComponent,服务器承受力测试组件BenchmarkComponent。

 

数据库(基于哲学绅士的ET棋牌Demo)

1_80BDG6[YMQV_YML}5@8BQ

数据库组件

一、Hotfix

1.DBQueryBatchRequestHandler : AMRpcHandler<DBQueryBatchRequest, DBQueryBatchResponse>

批量加入数据库缓存字典。

2.DBQueryJsonRequestHandler :  AMRpcHandler<DBQueryJsonRequest, DBQueryJsonResponse>

通过json批量加入数据库缓存字典。

3.DBSaveRequestHandler : AMRpcHandler<DBSaveRequest, DBSaveResponse>

保存数据到数据库。

4.DBSaveBatchRequestHandler : AMRpcHandler<DBSaveBatchRequest, DBSaveBatchResponse>

批量保存数据到数据库。

5.DBQueryRequestHandler : AMRpcHandler<DBQueryRequest, DBQueryResponse>

数据添加到数据库缓存字典。

二、Model

1.InnerMessage类中包含数据请求和数据回复相关的类。

(1)、数据请求类继承ARequest,包含有DBQueryRequest缓存请求类、DBQueryBatchRequest批量缓存请求类、DBQueryJsonRequest用Json缓存请求类、DBSaveRequest数据保存请求类、DBSaveBatchRequest数据批量保存请求类。

(2)、数据回复类继承AResponse,包含有DBQueryResponse缓存回复类、DBQueryBatchResponse批量缓存回复类、DBSaveResponse数据保存回复类、DBSaveBatchResponse数据批量保存回复类。

2.DBProxyComponent:用于进行数据缓存保存和保存到数据库操作。

3.DBComponent:连接数据库。

4.DBCacheComponent:数据库缓存组件。

5.DBTask类的子类DBSaveTask执行数据保存、DBSaveBatchTask批量数据保存、DBQueryTask查询数据库保存至数据缓存字典、DBQueryBatchTask批量查询数据库保存至数据缓存字典、DBQueryJsonTask用Json查询数据库保存至数据缓存字典。

三、数据库读写

(1)、原版ET数据库读写

1.创建需要读写的类,继承Entity。

T1TC`@ACG~F)Z@C_SH@$)FQ

2.读写数据,调用DBProxyComponent类中的方法查询或者保存。

查询方法有Query<T>(long id, bool needCache = true)按类名的ID查询、QueryBatch<T>(List<long> ids, bool needCache = true)批量按类名的ID查询、QueryJson<T>(string json, bool needCache = true)按类名用json进行自定义查询。

原版ET数据库读写2

保存方法有Save(Disposer disposer, bool needCache = true)按保存类中数据、SaveBatch(List<Disposer> disposers, bool needCache = true)批量保存类中数据、Save(Disposer disposer, bool needCache, CancellationToken cancellationToken)定时保存超时取消保存,保存时需要 EntityFactory.CreateWithId<AAA>(IdGenerater.GenerateId());实例化需要保存的类,AAA为需要保存的类名。

原版ET数据库读写3

(2)、棋牌Demo数据库读写

1.创建需要读写的类,继承EntityDB。

原版ET数据库读写4

2.EntityDB类上方添加标签 [BsonKnownTypes(typeof(AAA))],AAA为需要读写的类名。

原版ET数据库读写5

3.读写方法与原版ET相同。

 

ET添加修改消息

消息发送接收路线:例如消息发送路线:客户端–>网关服务器–>内部功能服务器–>网关服务器–>客户端,游戏启动时通过标签将协议码为键、消息类为值存入字典,将消息请求类作为键、消息处理类作为值存入字典,将消息通过下文第四步中的Session类由AChannel类Send发送,通过TCP或UDP发送到目标网关服务器,网关服务器接收到消息由网关消息助手类处理发给内部功能服务器,内部功能服务器处理的消息处理类处理,通过消息回复类作为载体将消息回传消息给网关服务器,网关服务器消息处理助手类中由消息回复类作为载体接收好数据被消息处理助手类回传给客户端,客户端用相同的消息回复类接收回传的数据进行使用。

服务器收发消息通过网关服务器gate进行,gate接收消息后根据情况将消息分发给其它服务器处理,其它服务器处理后消息回传给gate,再由gate发给客户端。

内部功能服务器实现分布式服务器功能:除Manager管理服务器和Location转发Actor的服务器之外的服务器均作为路由服务器,ActorProxyComponent消息管理组件作为路由信息存储组件存储本服务器使用的消息ID和ActorProxy类处理Actor消息类(发送、接收等),先读取路由信息存储组件中的缓存,缓存没有的情况下会由ActorProxy通过LocationProxyComponent服务器消息处理状态存储组件向Location转发Actor消息IP对应的编号、管理服务器发送key(Actor消息ID),Location服务器通过LocationComponent处理其它服务器发送的Actor消息ID获取消息的对应的IP,请求IP对应编号的服务器通过ActorProxyComponent或UnitGateComponent类读取IP编号,然后通过IP编号能获取到对应的IP和端口,从而发送消息给目标服务器。从Location服务器收到的Actor消息IP对应的服务器IP编号会存储在本地服务器缓存。

群主熊猫解析:Actor其实非常非常简单,别想的很复杂,一般分布式游戏服务器,跨进程发消息,比如A玩家在Map1,B玩家在Map2,A是B的好友,那么B并不知道A在哪个Map上,B玩家怎么给A玩家发消息呢?一般有个friend server,A可以在进入map1的时候把自己的位置注册到friend server上,那么friend server就知道了A玩家的位置,B发消息就可以通过friend server来转发消息给A。那么我们可以简化一下这个过程,A玩家登录进入Map1的时候把自己注册到Location server,告诉location server自己在Map1上面,B要发消息给A,直接去查询location server不就知道A在哪个map上了吗,比如B查到A的位置在Map1上面,就可以直接发消息到map1,消息里面带了一个actorid也就是A玩家的id,Map1收到这个消息发现这是一个IActorMessage,就会根据这个actorId找到A,把消息交给A处理。这就是actor位置透明的原理。 B发消息给A用的的ActorProxy,因为A一般在一个进程会呆比较长的时间,B没必要每次都去查A的位置,第一次发送不知道A的位置,然后去location查了A的位置,之后B知道了A的位置就不用查了,直接发到Map1就行了。问题是万一A不在Map1了,这时B发到Map1的消息根据A的id就会在Map1上找不到A。这时会返回一个not found actor的错误给B,B收到这个消息会重新去location server查A的位置,再重新发送。

此分布式服务器框架如果不够用,瓶颈在于Location服务器的消息处理速度,可增加location服务器数量解决:在将Actor消息的ID与与所在服务器的IP对应编号作为消息传给所有Location进行进行同ETDemo中Location服务器相同的处理,在处理Actor消息时,只需要向多个location服务器中的任意一个发送消息即可获取到Action消息对应的IP编号。此方法瓶颈在于location服务器内能存储的Action消息ID和IP编号的键值对个数。

此分布式服务器框架类似于即时通信服务器架构中的一种,Location服务器提供存储和查询目标消息服务器的IP服务:

分布式服务器

https://www.cnblogs.com/myd620/p/6081100.html  即时通信服务器架构

http://blog.csdn.net/u010738184/article/details/49472795

分布式系统 (大规模分布式系统原理解析和架构实践)

https://www.cnblogs.com/liulun/p/3625941.html

分布式缓存服务器设计原理

 

物理分布式服务器发布
方法一:更改LandlordsCore-master\Config\StartConfig文件下的IP端口配置文件,将需要发布在物理服务器上的服务器编号对应的配置最后一项设置为 “ServerIP” : “*”  ,将不需要发布在此物理服务器上的服务器编号对应的配置最后一项设置为  “ServerIP” : “”  ,然后启动服务器即可实现物理分布式部署(启动LandlordsCore-master\netcoreapp2.0下的app.dll,可以使用bat批处理:dotnet App.dll –appId=AAA –appType=Manager –config=../Config/StartConfig/BBB,如dotnet App.dll –appId=1 –appType=Manager –config=../Config/StartConfig/LandlordsCore.txt)。
方法二:部署时,将需要部署的服务器的服务器IP位置处填上  *  号,在不需要部署的服务器IP处删除*,保存,然后点击启动即可。
服务器部署
 

一、Actor消息

1.在协议码类Opcode类添加协议码。

Actor消息1

2.在OuterMessage文件中添加消息类。

如果需要序列化添加protobuf序列化标签[ProtoContract]

注册消息标签[Message(Opcode.Frame_ClickMap)]

帧消息继承帧同步抽象类AFrameMessage

添加protobuf属性序列化标签[ProtoMember(int a)],a为唯一

Actor消息2

3.添加消息实现类。

添加消息实现标签[MessageHandler((int)Opcode.XX)],XX参数为对应的消息协议码

继承消息实现的抽象类AMHandler<BB>,BB参数为对应消息的消息类,需要序列化则添加protobuf相关标签。此类为消息接收方接收到消息后处理消息的类。

Actor消息3

4.添加消息转发组件

Actor消息4

5.发送消息

通过SessionComponent类中SessionComponent.Instance.Session调用Session中的方法发送消息。

Actor消息5

客户端:

Actor消息6

服务端:

Actor消息7

Actor消息8

 

附:来自TIM的在线文档”ET框架笔记”,点击查看:
https://docs.qq.com/doc/BBHvys04uyFR11t2171PDPa34yGBCe2XqPFc3