详细 https://github.com/game-town/ioGame/releases/tag/17.1.55
[186] 增强 ProtoDataCodec
当 ExternalMessage.data 为 null 时,使用空数组来解析序列化;可以确保 action 参数不会为 null,使得开发者拥有更好的编码体验。
将 ActionCommandTryHandler 逻辑合并到 ActionCommandHandler
DevConfig.me 标记为过期,并将 DevConfig 改为静态类;
把 MethodParsers.me 方法标记为过期,并将 MethodParsers 改为静态类;
其他更新
<netty.version>4.1.97.Final</netty.version>
<lombok.version>1.18.28</lombok.version>
[#174] fix action 交给容器管理时,实例化两次的问题
获取游戏对外服的数据与扩展,获取ResponseCollectExternalMessage 新增 optionalAnySuccess 方法,方便得到成功的 optional
public String getUserIp() {
ResponseCollectExternalMessage message = ...
return message
.optionalAnySuccess()
// 得到返回值
.map(ResponseCollectExternalItemMessage::getData)
// 将为 String
.map(Objects::toString)
// 如果没获取到给个空串,调用方就不需要做 null 判断了。
.orElse("");
}
压测&模拟客户端请求模块,新增模块名标识
public class BagInputCommandRegion extends AbstractInputCommandRegion {
@Override
public void initInputCommand() {
this.inputCommandCreate.cmd = BagCmd.cmd;
this.inputCommandCreate.cmdName = "背包模块";
}
}
新游戏对外服新增 HttpRealIpHandler,用于获取玩家真实 ip 支持
游戏对外服 webSocket 使用 nginx 代理,也能获取真实的玩家 ip
public class MyExternalServer {
... ...省略部分代码
public ExternalServer createExternalServer(int externalPort) {
... ...省略部分代码
// 游戏对外服 - 构建器
DefaultExternalServerBuilder builder = ...
builder.setting().setMicroBootstrapFlow(new WebSocketMicroBootstrapFlow() {
@Override
protected void httpHandler(PipelineContext context) {
super.httpHandler(context);
/*
* HttpRealIpHandler 是框架内置的一个 handler。
* 添加上后,即使是通过 nginx 转发,也可以得到玩家真实的 ip
*/
context.addLast("HttpRealIpHandler", new HttpRealIpHandler());
}
});
// 构建游戏对外服 https://www.yuque.com/iohao/game/ea6geg
return builder.build();
}
}
https://github.com/game-town/ioGame/issues/172
新增 webSocket token 鉴权、校验支持
有时,我们需要在 WebSocket 建立连接前做 token 相关鉴权、校验的业务。ioGame 支持此类业务的扩展,我们可以在游戏对外服部分做相关扩展;
简单的说,如果校验没通过,我们就不建立 ws 连接了,在 http 阶段就结束所有流程,可以有效的减少恶意长连接。
相关文档与使用示例 https://www.yuque.com/iohao/game/tb1126szmgfu6u55
日志相关调整
移除 light-log 模块,统一使用 lombok slf4j 相关注解
压测&模拟客户端增强
新增 SplitParam,方便模拟测试时,解析控制台输入参数的获取
private void useRequest() {
InputRequestData inputRequestData = () -> {
ScannerKit.log(() -> log.info("输入需要使用的背包物品,格式 [背包物品id-数量]"));
String inputType = ScannerKit.nextLine("1-1");
SplitParam param = new SplitParam(inputType);
// 得到下标 0 的值
String id = param.getString(0);
// 得到下标 1 的值,如果值不存在,则使用默认的 1 代替
int quantity = param.getInt(1, 1);
... ... 省略部分代码
};
ofCommand(BagCmd.use).callback(BoolValue.class, result -> {
var value = result.getValue();
log.info("value : {}", value);
}).setDescription("使用背包物品").setInputRequestData(inputRequestData);
}
文档生成增强,增加 action 参数注释说明.
文档生成增强,返回值注释说明.
fix 在 pom 中引入本地 jar 时,文档解析的错误。
详细:https://github.com/game-town/ioGame/releases/tag/17.1.46
文档:https://www.yuque.com/iohao/game/tc83ud
介绍
此模块是用于模拟客户端,简化模拟工作量,只需要编写对应请求与回调。
使用该模块后,当我们与前端同学联调某个功能时,不需要跟前端哥们说:在点一下、在点一下、在点一下了。这种“在点一下”的交流联调方式将成为过去式。
除了可以模拟简单的请求外,通常还可以做一些复杂的请求编排,并支持复杂业务的压测。模拟测试的过程是可互动的,但也支持测试自动化。
与单元测试不同的是,该模块可以模拟真实的网络环境,并且在模拟测试的过程中与服务器交互是可持续的、可互动的。
可互动模式是用于调试测试某些功能。在互动的过程中,开发者可以在控制台中指定执行某个模拟请求命令,并且支持在控制台中输入一些动态的请求参数,从而让我们轻松的测试不同的业务逻辑走向。
关于可互动部分,需要将后续文档阅读完后才能知道其具体意思。
特点
#115:广播的数据为空时,广播虽然是成功的,但是打印广播日志报错了 游戏对外服增加路由是否存在检测
参考:https://www.yuque.com/iohao/game/ea6geg#EeWiH
新游戏对外服中增加路由存在检测。当路由不存在时,可以起到抵挡的作用,而不必经过其他服务器。
#114:accessAuthenticationHook.addIgnoreAuthenticationCmd添加根据cmd来的 支持玩家与多个游戏逻辑服的动态绑定
文档:动态绑定游戏逻辑服
动态绑定游戏逻辑服,指的是玩家与游戏逻辑服绑定后,之后的请求都由该游戏逻辑服来处理。
玩家动态绑定逻辑服节点后,之后的请求都由这个绑定的游戏逻辑服来处理,可以实现类似 LOL、王者荣耀匹配后动态分配房间的效果。
支持玩家与多个游戏逻辑服的动态绑定。
使用场景
跨服活动、跨服战斗等。
动态绑定游戏逻辑服可以解决玩家增量的问题,我们都知道一台机器所能承载的运算是有上限的;当上限达到时,就需要增加新机器来分摊请求量;如果你开发的游戏是有状态的,那么你如何解决请求分配的问题呢?在比如让你做一个类似 LOL、王者荣耀的匹配,将匹配好的玩家分配到一个房间中,之后这些玩家的请求都能在同一个游戏逻辑服上处理,这种业务你该如何实现呢?
使用框架提供的动态绑定逻辑服节点可以轻松解决此类问题,而且还可以根据业务规则,计算出当前空闲最多的游戏逻辑服,并将此游戏逻辑服与玩家做绑定,从而做到均衡的利用机器资源,来防止请求倾斜的问题。
#113:增加 Banner 打印版本、内存占用、启动耗时等信息。 新版本游戏对外服
文档:新游戏对外服使用
迁移指南 :迁移到新版游戏对外服
【新版游戏对外服】用于取代【旧的游戏对外服】,如果条件允许,请尽可能做迁移,整体工作量很少。旧的游戏对外服将不在做功能上的新增,如果存在 bug 将会继续修复,维护期会持续到下个大版本前。
从架构简图中,我们知道了整体架构由三部分组成 1.游戏对外服、2.游戏网关、3.游戏逻辑服。本篇将介绍游戏对外服这部分,及功能扩展等相关的。
游戏对外服的职责
扩展场景
游戏对外服主要负责与用户(玩家)的连接。假设一台硬件支持最多建立 5000 个用户连接,当用户量达到 7000 人时,我们可以增加一个游戏对外服来进行流量控制和减压。
由于游戏对外服的扩展性和灵活性,可以支持同时在线玩家从几千人到数千万人不等。这是因为,通过增加游戏对外服的数量,可以有效地进行连接的负载均衡和流量控制,使得系统能够更好地承受高并发的压力。
连接方式的切换、支持、扩展
ioGame 已提供了 TCP、WebSocket、UDP 连接方式的支持,并提供了灵活的方式来实现连接方式的切换。可以将 TCP、WebSocket、UDP 连接方式与业务代码进行无缝衔接。开发者可以用一套业务代码,无需任何改动,同时支持多种通信协议。
如果想要切换到不同的连接方式,只需要更改相应的枚举即可,非常简单。在不使用 ioGame 时,将连接方式从 TCP 改为 WebSocket 或 UDP 等,需要进行大量的调整和改动。然而,在 ioGame 中,实现这些转换是非常简单的。此外,不仅可以轻松切换各种连接方式,而且可以同时支持多种连接方式,并使它们在同一应用程序中共存。
连接方式是可扩展的,而且扩展也简单,这意味着之后如果支持了 KCP,那么将已有项目的连接方式,如 TCP、WebSocket、UDP 切换成 KCP 也是简单的。
需要再次强调的是,连接方式的切换对业务代码没有任何影响,无需做出任何改动即可实现连接方式的更改。
新游戏对外服 - UML
游戏对外服由两部分构成
我们只需要关注 ExternalCore 这部分,新版游戏对外服总体来说只有四个核心接口,如果你只打算做功能扩展,只需要关注 MicroBootstrapFlow 接口就好了。
接口名 | 描述 |
---|---|
ExternalServer | 由 ExternalCore 和 ExternalBrokerClientStartup 组成的一个整体。职责:是启动 ExternalCore 和 ExternalBrokerClientStartup 。 |
ExternalCore | 与真实玩家连接的服务器,也是通信框架屏蔽接口。ExternalCore 帮助开发者屏蔽各通信框架的细节,如 Netty、mina、smart-socket 等通信框。ioGame 默认提供了基于 Netty 的实现。职责:与真实玩家连接的服务器 |
MicroBootstrap | 与真实玩家连接的服务器,服务器的创建由 MicroBootstrap 完成,实际上 ExternalCore 是一个类似代理类的角色。MicroBootstrap 帮助开发者屏蔽连接方式的细节,如 TCP、WebSocket、UDP 等。 职责:与真实玩家连接的【真实】服务器 |
MicroBootstrapFlow | 与真实玩家连接【真实】服务器的启动流程,专为 MicroBootstrap 服务。开发者可通过此接口对服务器做编排,编排分为:构建时、新建连接时两种。框架提供了 TCP、WebSocket、UDP 的实现;开发者可以选择性的重写流程方法,来定制符合自身项目的业务。职责:业务编排,也是开发者在扩展时接触最多的一个接口。 |
其他更新
<scalecube-cluster.version>2.6.15</scalecube-cluster.version>
<netty.version>4.1.93.Final</netty.version>
[#127:业务参数自动装箱、拆箱基础类型-long] DebugInOut,可限制某些 action 不输出 log
使用文档 https://www.yuque.com/iohao/game/pf3sx0#esnXX ,文档中提供了两种参考示例:
@ActionController(1)
public class DemoAction {
@ActionMethod(3)
@IgnoreDebugInout
public String hello() {
// 给 action 添加上自定义注解 IgnoreDebugInout 后,将不会打印 debug 信息
return "hello";
}
}
[#132:light-protobuf可以支持枚举的序列化吗] 集群重启后组网异常
导致集群数量对不上,触发的事件顺序可能是 ADDED、REMOVED,也可能是REMOVED、ADDED,现已修复。
其他更新
<scalecube-cluster.version>2.6.14</scalecube-cluster.version>
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络游戏服务器框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。
ioGame 是一个 java 网络游戏服务器框架,有以下特点:
- 无锁异步化、事件驱动的架构设计
- 支持 websocket 和 socket 两种通信协议
- 支持 protobuf、json 等不同的通信协议
- 集群无中心节点、集群自动化、分布式的设计
- 轻量级,不依赖第三方中间件或数据库就能支持集群、分布式
- 提供多种通讯方式,且逻辑服之间可以相互跨机器通信
- 与 spring 和其他框架融合方便
- 学习成本低,开发体验好
- 支持多服单进程、多服多进程的启动和部署方式
- 提供游戏文档生成的辅助功能
- 包体小、启动快、内存占用少
- 提供优雅的路由访问权限控制
- 提供了灵活的线程扩展、设置
ioGame 是一个专为网络游戏服务器设计的轻量级框架,它可以帮助你快速地搭建和运行自己的游戏服务器。它适用于各种类型和规模的网络游戏,无论是 H5、手游还是 PC 游戏,无论是简单的聊天室,还是复杂的全球同服、回合制游戏、策略游戏、放置休闲游戏、即时战斗、MMORPG 等,ioGame 都可以满足你的需求。
ioGame 在打包、内存占用、启动速度等方面也是优秀的。打 jar 包后大约 15MB,应用通常会在 0.x 秒内完成启动,内存占用小。详细请看 快速从零编写服务器完整示例。
在生态融合方面,ioGame 可以很方便的与 spring 集成(5 行代码);除了 spring 外,还能与任何其他的框架做融合,如:solon ... 等,从而使用其他框架的相关生态。
在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架,而无需在安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf协议编译工具 ... ...等。
在通讯方式方面,大部分框架只能支持推送(广播)这一类型的通讯方式;而 ioGame 则提供了 5 种类型的通讯方式,分别是单次请求处理、推送、单个逻辑服间的相互通讯、与同类型多个逻辑服相互通讯、脉冲通讯。通过对各种通讯方式的组合使用,可以简单完成以往难以完成的工作,并且这些通讯方式都支持跨进程、跨机器通信。
在通信方面,ioGame 让开发者用一套业务代码,同时支持 WebSocket 和 TCP 两种通信协议,无需做任何改动。这意味着一个游戏服务器可以同时接入 WebSocket 和 TCP 的游戏客户端。
在通信协议方面,ioGame 让开发者用一套业务代码,就能轻松切换和扩展不同的通信协议,如 Protobuf、JSON 等。只需一行代码,就可以从 Protobuf 切换到 JSON,无需改变业务方法。
在集群方面,ioGame 的 Broker (游戏网关)采用无中心节点、自动化的集群设计,所有节点平等且自治,不存在单点故障。集群能够自动管理和弹性扩缩,节点加入或退出时,能够自动保证负载均衡和数据一致性,不影响服务可用性。
在分布式方面,ioGame 的逻辑服使用了分布式设计思想,将服务器分为游戏对外服、游戏逻辑服等不同层次,并且每一层都有明确的职责和接口。这样可以提高代码可读性和可维护性,并且方便进行水平扩展。
在学习成本方面,ioGame 的学习成本非常低,可以说是零学习成本,即使没有游戏编程经验,也能轻松上手。开发者只需掌握普通的 java 方法或 webMVC 相关知识,就能用框架开发业务。框架不要求开发者改变编码习惯,而是自身适应开发者的需求。
在开发体验方面,ioGame 非常注重开发者的开发体验;框架提供了 JSR380验证、断言 + 异常机制、业务代码定位... ...等诸多丰富的功能,使得开发者的业务代码更加的清晰、简洁;
在业务的并发方面,框架为开发者解决了单个玩家的并发问题,也提供了解决同一房间或业务内多个玩家并发问题的解决方法;框架在线程的扩展性上提供了友好的支持,并不是只能提供呆板的线程数量设置;详细请看 ioGame 线程相关。
在分布式开发体验方面,通常在开发分布式应用时是需要启动多个进程的。这会让调试与排查问题变得非常困难,从而降低开发者的效率、增加工作量等,这也是很多框架都解决不了的问题,但 ioGame 做到了!ioGame 支持多服单进程的启动方式,这使得开发者在开发和调试分步式系统时更加简单。
与前端对接联调方面,ioGame 提供了游戏文档生成的辅助功能,可以做到代码即对接文档。简单地说,当业务代码编写完后,框架会自动生成最新的文档。如果没有游戏文档的生成,那么你将要抽出一些时间来编写、维护对接文档的工作,而且当团队人数多了之后,文档就会很乱、不同步、不是最新的、忘记更新等情况就会出现。
在部署方面,ioGame 支持多服单进程的方式部署,也支持多服多进程多机器的方式部署;在部署方式上可以随意的切换而不需要更改代码。日常中我们可以按照单体思维开发,到了生产可以选择使用多进程的方式部署。
开发者基于 ioGame 编写的项目模块,通常是条理清晰的,得益于框架对路由的合理设计,同时也为路由提供了优雅的访问权限控制。当我们整理好这些模块后,对于其他开发者接管项目或后续的维护中,会是一个不错的帮助(模块的整理与建议)。或许现阶段你感受不到这块的威力,随着你深入地使用实践就能体会到这么设计的诸多好处与优势。
开发者基于 ioGame 编写的项目,通常是语法简洁的、高性能的、低延迟的;框架最低要求使用 JDK17,这样即可以让项目享受到 ZGC 带来的改进,还能享受语法上的简洁。从 JDK17 开始 ZGC 远低于其亚毫秒级暂停时间的目标,可以在不影响游戏速度的情况下,清理掉多余的内存。这样就不会出现卡顿或者崩溃的问题了,相当于在项目中变相的引入了一位 JVM 调优大师,详细请看 JDK 17 垃圾回收 GC 性能飞跃提升。
综上所述,ioGame 是一个非常适合网络游戏开发的框架。可以让你轻松地创建高性能、低延迟、易扩展的游戏服务器,并且节省时间和资源。如果你想要快速地开发出令人惊艳的网络游戏,请不要犹豫,立即选择 ioGame 吧!框架屏蔽了很多复杂且重复性的工作,并可为项目中的功能模块结构、开发流程等进行清晰的组织定义,减少了后续的项目维护成本。
相信你已经对 ioGame 有了一个初步的了解,虽然还有很多丰富的功能与特性没有介绍到,但你可以通过后续的实践过程中来深入了解。感谢你的阅读,并期待你使用 ioGame 来打造自己的游戏服务器。