任务43:重要知识点(长期更新中...)
更新中...
#################### 学习方法 ####################
根据自己的思维习惯选择不同的学习方式。建议先优先建立对服务端通信往来的模型,先不要过于关注每句代码全部想一开始就明白。
知道如何通信,能把注册,登录,进房间,发牌这些如何在map,gate,reale之间建立通信往来,先跟着主线做出来,能最直观直接的体会到,这个更关键。
比如说:
ET的事件系统,不明白为什么这样写,但是课程里反复告诉你怎么用了。
FairyGUI,ET UI组件,不明白为什么这样写,但能看明白怎么用了。另个你得会不用FairyGUI应该也能做出来,要理解核心通信。
代码很多使用了特性,泛型,接口,抽象类与方法,扩展方法。跟着写跟着用,过段时间自己全会用了,越来越加深理解。
记住:整个课程的学习重点关注的是服务端通信,请求,消息,响应请求的Handler,通用的服务端功能实现。
#################### 学习方法 ####################
开发运行环境:
前端需要.net framework,后端需要.netcore
详细的环境安装 https://www.taikr.com/course/1053/task/30933/show
理解项目管理:
前端可以创建程序集.asmdef来管理项目代码,别都直接放在Assets下面,用Unity自动生成的Assembly-CSharp管理项目代码。https://www.taikr.com/course/1053/task/30931/show
代码都需要在一个项目中编译后才能被执行。一个项目会生成一个dll,你的C#项目都是.net运行时中运行这些dll来执行的。
Unity会帮你生成解决方案.sln,和c#项目.csproj。
服务端自己创建.sln,和c#项目.csproj,项目可以引用别的项目,也就是不同dll的引用。
ETCore的使用
Unity项目中,只需要要包含ET.Core项目(核心,与服务端代码一样),就能使用ET来进行网络请求与通信,Model项目中包含了少量现成提供可复用的组件,我们自己游戏的代码可以放在Model中,也可以另外创建一个项目引用ET.Core与Model即可。
需要引用ThirdParty项目,这里有mongo,protobuf,fairgui这些第三方sdk。
服务端项目中,系统逻辑与Handler都在Hotfix项目中编写,你自己项目的服务端代码主要在这里。后端ET.Core项目中可以加你自己游戏的实体,组件,系统类。
Handler是请求的响应,与功能逻辑实现的地方。System是组件的扩展方法,来帮助把需要的组件加入到系统的生命周期里(start,load,awake,update等)。
消息指令与消息体在ET.Core项目中 \ET.Core\Module\Message\目录下。
Session使用
用地址创建session
远程地址:127.0.0.1:10002
Session sessionRealm = Game.Scene.GetComponent<NetOuterComponent>().Create("127.0.0.1:10002"); Session sessionRealm = Game.Scene.GetComponent<NetOuterComponent>().Create(GlobalConfigComponent.Instance.GlobalProto.Address);
GlobalConfigComponent.Instance.GlobalProto.Address就是配置文件中获取到像上面的远程地址。
用IPEndPoint创建session
public IPEndPoint(long address, int port);
IPEndPoint realmIPEndPoint = new IPEndPoint(Int64.Parse("127.0.0.1"),10002); Session realmSession = Game.Scene.GetComponent<NetOuterComponent>().Create(realmIPEndPoint);
不需要返回发送消息 session.Send
Send方法的参数是一个消息体
realmSession.Send(new A0004_PlayerOnline_G2R() { UserID = user.UserID, GateAppID = config.StartConfig.AppId });
发送请求获得返回 session.Call
Call方法的参数是一个请求消息体,返回一个响应消息体
A1002_SetUserInfo_G2C SetUserInfo_Ack = (A1002_SetUserInfo_G2C)await SessionComponent.Instance.Session.Call(SetUserInfo_Req);
消息指令、消息体
消息指令是前后端,不同服务端之间的“接头暗号”,收到消息后,通过指令就知是什么消息体类型了,或者找出对应的Handler来执行。
消息体,是把消息内容的不同字段构建一个消息体类型的实例,用实例属性来使用消息数据。
ET是先用数据构建消息体实例,把消息对象序列化为json或profobuf数据进行传送,收到消息再反序列化为消息对象在程序中使用。
消息与handler命名参考举例:消息名需要先知道他是什么功能,再怎么往来。消息处理handler需要先知道从哪来,再是什么功能。方便开发时保持思路清晰。
[功能表达]+[往来] :GetUserInfo_C2G,GetUserInfo_G2C
当然如果你更习惯统一:C2G_TestMessage
如果是IActorMessage :Actor_MatchSucess_M2G
收到消息后处理handler :M2G_MatchSucess_Handler
认证服务Realm:R ,网关服务Gate:G,地图服务Map:M,客户端Client:C
消息指令与消息体定义
message C2G_TestMessage // IRequest
请求名后面带上 // IRequest 这样生成的消息体就会继承IRequest
message G2C_TestMessage // IResponse
返回名后面带上 //IResponse 这样生成的消息体就会继承IResponse
//测试向服务器返回消息 message G2C_TestMessage // IResponse { int32 RpcId = 90; int32 Error = 91; string Message = 92; }
HotfixMessage.cs,HotfixOpcode.cs,InnerMessage.cs,InnerOpcode.cs,OuterMessage.cs,OuterOpcode.cs
在我们的课程里,统一把他们都放在这个目录下:
\Assets\ET.Core\Module\Message\
InnerMessage:不同服务之间通信消息
OuterMessage:前后端通信消息
HotfixMessage:前后端通信消息,无热更的ETCore来说与OuterMessage没区别
自动生成消息指令与消息体类
Proto的unity编辑器扩展工具,放在Assets>Editor目录中 Proto2CsEditor.zip
proto生成工具 Proto.zip
https://www.taikr.com/course/1053/task/30953/show
更新 .proto 文件后,到unity中找到菜单点Tools>Ptoto2CS工具,确认下重新生成的消息体类与指令脚本,复制一份放到服务端。
前端消息类与指令脚本在 \Assets\ET.Core\Module\Message\
后端消息类与指令脚本复制前端生成的文件到 \Server\ET.Core\Module\Message\
断线重连要点:
- 处理好与用户主动下线的关系,别主动下线下线不了
- 客户端发现断线,请求重连
- 服务端发现断线,保留用户数据,游戏地图中数据15分钟
- 服务端收到重连请求,把重连数据发给客户端
状态同步,还要理清楚哪些是触发式保存的数据,哪些是每分钟保存的数据,还不能冲突了,漏了。
比如说:
角色走来走去,背包装备移这个格子那个格子,技能拖到不同的工具条格子,装备换来换去,许多这类玩家的“无聊”操作并不会触发保存数据库,是每分钟统一保存角色数据的。
比如新获得了装备,经验,升级,货币增加,接,完成任务这些有意义的东西会更新角色数据内存和更新数据库。
实体间Actor通信:
理解为什么要用actor通信:
Entity.Id是实体的身份证号,instanceID是居住证号,实体instanceID是会换的,比如到了别的地图。actor系统会保存你的身份证和你在哪个地图的居住证。如果用居住证能找到你,就用instanceId把消息发给你了,如果找不到,就会用身份证找到你新的居住证,再把消息发给你。
总结一下几种给实体添加消息组件:
//网关上的user实体是不是变动的,加消息组件,没有参数也没有AddLoaction() user.AddComponent<MailBoxComponent>(); //session实体是客户端与网关的连接session,向此实体发消息,会转发到客户端,加消息组件带MailboxType.GateSession参数 session.AddComponent<MailBoxComponent, string>(MailboxType.GateSession); //room,gamer实体会迁移地图,加消息组件有AddLoaction() room.AddComponent<MailBoxComponent>().AddLocation(); newgamer.AddComponent<MailBoxComponent>().AddLocation();
命令行运行FileServer.dll
打开命令行工具到达FileServer目录
输入命令:dotnet FileServer.dll
C:\Users\Rman-xvr>e: E:\>cd E:\ETCoreLandlords\ET0X_Landlords_Client\FileServer E:\ETCoreLandlords\ET0X_Landlords_Client\FileServer>dotnet FileServer.dll E:\ETCoreLandlords\ET0X_Landlords_Client\Release\ Hosting environment: Production Content root path: E:\ETCoreLandlords\ET0X_Landlords_Client\FileServer Now listening on: http://[::]:8088 Now listening on: http://[::]:8080 Application started. Press Ctrl+C to shut down.
Protobuf : repeated类型
使用Game.Scene
Game.Scene 是ETCore框架的全局实体对象,如果你有某种组件,需要在全局范围调用他的属性和方法,那就应该在需要的时候把此组件添加给Game.Scene。
Game.Scene.AddComponent<XXX组件>();
Game.Scene.GetComponent<XXX组件>();
ET.Core事件
Handler特性
[MessageHandler(AppType.Gate)]
UIFactory特性
[UIFactory(FUIType.SetUserInfo)]
创建实体或组件
向组件扩展方法传参
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)