[Unity 3D] ET 框架网络模块的抽离、重构与模块化

在本文,笔者介绍一下这段时间重构的 ET 网络模块,希望能够遇到需要它的人吧。
ET: 一个双端 C# Unity 游戏开发框架,网络 + 热重载的功能亮点; Attribute + 扩展方法 + 反射的底层驱动逻辑;ECS 架构特色。

前言

做一个飞屏软件,负责技术的同事敲定用 ET ,emmm.... 内心是抗拒的,毕竟项目不大,但反过来想想,项目不大正好是个学习 ET 的契机。
因为我负责控制端,用不到热更,并且习惯了在 Unity 内做开发,所以我决定把 ET 的网络模块剥离出来,用在我负责的控制端上,这样一来,既能够与 ET 后台对接,也能保持我自己的开发习惯。

当然,非要说细节上为啥抗拒,其实是有几点的,作为 ET 0 基础小白斗胆小声BB几句:

  1. 为了热重载,严格约束用户按照 ET ECS 架构开发,因此开发一个应用得整好几个解决方案,而且还不是常规的打开方式,跨解决方案的引用查找还挺难(可能是我太菜哈)。
  2. 不需要热更,ILRuntime 插件冗余了,不能忍,如果考虑热更那也只会是对现有开发模式无侵入的 HCLR。
  3. 修改在 Model 、 Hotfix 程序集,需要编译才能看到修改的效果,而开启自动编译一度让我困惑。
  4. 框架文件结构限定的比较死,由于很多路径都是写死在逻辑中,原本仅有一个 Server ,一个 Client,想要做 一个 Server + 两个 Client 令初次接触 ET 的我无从下手(当然,现在整明白了,改一些脚本中文件夹路径就行,按说 ET7 啥都内敛到了 Unity 内部,也不预设热更方案也就没有这些痛点了)。

抽离

  • 更新 ET6.0 Github最新提交后,一通复制粘贴,把网络部分梳理到新工程中
  • 转移 Protobuf、Litjson 、ETTask、Timer 、KCP 到新工程。
  • 删除 Litjson 、Protobuf 中为适配 ILRuntime 而撰写的逻辑。
  • 此时,网络模块已经大体抽离,然后再根据报错,将缺失的、离散在周边的脚本汇集整理。
  • 到了这一步,网络模块还是 ECS 架构的(由于模块无需热更, ECS 没有拆分在各个程序集)所以一通改造,把各个功能模块的 ECS 整合成单脚本(其实就是把 Component的字段,System 中的 Awake 、Update 等方法整到一起,使用 MonoBehaviour 驱动)。
  • ET EventSystem ,ET 的心脏,用于在启动或热重载时根据 Attribute 做 Type 预绑定,同时也是一个事件总线。网络模块、ECS以及事件分发都依赖它,一通删除,保留网络消息类型注册部分即可。
  • 断开对 ET Entity 的依赖:删除继承关系,同时将 GetChild 、AddChild 进行简单的改写成实例查询和实例构建就好了。
  • 两个有意思的地方:LitJson 保留是为了 网络消息实例以 json 输出,方便log;KCP 最后被干掉了是因为 ET6.0 为了通用,即便是 KServer 、KChannel 也默认不使用 KCP。

重构

  • 管理器性质的组件都依赖了 MonoBehaviour 驱动,但他们多为管理器性质,所以笔者将他们改为静态类。
  • 对管理器性质的组件的初始化放在 ET Eventsystem 中统一按顺序进行(比如 opcode管理器就要优先于其他消息分发管理器)。
  • 对管理器性质的组件的 Update 统一放在 ET Eventsystem 中统一使用 PlayerLoop 驱动。
  • 作为底层核心网络消息,将 Ping 消息 OuterMessage 中单独抽离出来,实现网络模块对 OuterMessage 零依赖。
  • 重新设计非 RPC 网络消息的监听与取消监听,实现非 RPC 消息在继承了 MonoBehaviour 的类更方便的被捕获。
  • 代码生成:实现非RPC 网络消息处理器的一键生成;修正 OuterMessage 的一键生成逻辑,跳过 Ping 消息。
  • 引入 Loom 做线程间数据传递,剔除原有的带 Thread 关键字的组件,避免了不必要的依赖注入,使用 using static Loom;的形式简化多线程间数据的投递。

模块化

借助 Unity 官方 Assembly Definition File ,我们可以在 Unity 项目中轻松的模块化 ET 网络模块。

  • 首先,将依赖的插件抽离,放在 ThirdPart,为他们加上各自的 .asmdef 文件,使其模块化
  • 然后,将用户自定义的消息类 (OuterMessage.cs 和 OuterOpcode.cs)抽离,网络模块对其 0 依赖,方便随时剔除,随时生成,随时更新。
  • 网络模块重构成以下形式:


可见:

  • ettask 、timer 、litjson、protobuf 都成了独立的程序集。
  • 网络核心又拆分出 editor + runtime + generated(generated 为一键生成的 outermessage 和 messagehandler)

使用

  1. clone 本项目,将文件夹 ET Network Module 拷贝到你的项目中(可考虑自行改为 UPM )
  2. 删除 Generated 文件夹。
  3. 如果有代码引用了 OuterMessage 中的类型,则这个代码所在的文件夹改名,加上 ~ (波浪号)完成编译后再删除波浪号
  4. 约定:前后端公用的 outermessage.proto 中 Ping 消息置顶。
  5. 通过 Tools 菜单中提供的工具,依次生成 OuterMessage.cs 、OuterOpcode.cs 以及各个非 RPC 消息处理器
  6. 调用 ET 原生 API:call + send 实现通信,var response = await Session.call(new SomeRPCRequest()) 或者 Session.Send(new NoRPCRequest())
  7. 非 RPC 消息的监听:使用 using static MessageHandler 即可在自己的类中通过 ListenSignalRemoveSignal 处理感兴趣的网络消息,示例代码如下:
using ET;
using UnityEngine;
using static MessageHandler;
public class HandlerUsageCase : MonoBehaviour
{
    private void Start()
    {
        ListenSignal<M2C_CreateMyUnit>(OnMyUnitCreated);
        ListenSignal<M2C_CreateUnits>(OnUnitsCreated);
    }

    private void OnUnitsCreated(Session arg1, M2C_CreateUnits arg2)
    {
        // 撰写你自己的逻辑
    }
    private void OnMyUnitCreated(Session arg1, M2C_CreateMyUnit arg2)
    {
        // 撰写你自己的逻辑
    }
    private void OnDestroy()
    {
        RemoveSignal<M2C_CreateMyUnit>(OnMyUnitCreated);
        RemoveSignal<M2C_CreateUnits>(OnUnitsCreated);
    }
}

演示

演示一:消息生成,消息处理器生成

code generate

演示二:测试与 ET 服务器通信(登录网关,登录地图,Ping(心跳))

写到最后

  • 为了方便的测试此 ET 网络模块,提供 ET6.0 示例 Server 编译而来的 .exe 文件,通过菜单 “Tools/Start Test Server” 开启。
  • 需要留意的是,因为彻底的重构,导致了业务逻辑代码必不可能复用,所以 ET 服务器的 AI压测、AI陪玩啥的怕是用不了,这点大家应该是明了的。
  • 本文配套项目地址:https://github.com/Bian-Sh/ET-Network-Module

原创作品,转载请注明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容