Releases: iohao/ioGame
Netty 网络游戏服务器框架 ioGame 17.1.44
主要更新
[#138] 提供协议碎片的工具类,方便协议碎片在广播时的使用
代码中演示了协议碎片相关的使用,通过工具类,可以让一些基础类型在使用上更简便。
对应的包装类中,都提供了静态 of 方法;
框架支持的包装类可到 框架支持的自动装箱、拆箱基础类型 查询。
... ... 省略部分代码
private static void test() {
// 给客户端广播一个 int 值 : 1
var bizData = WrapperKit.of(1);
// 广播上下文
CmdInfo cmdInfo = CmdInfo.getCmdInfo(DemoBroadcastCmd.cmd, DemoBroadcastCmd.broadcastMsg);
BroadcastContext broadcastContext = BrokerClientHelper.getBroadcastContext();
broadcastContext.broadcast(cmdInfo, bizData);
// 给客户端广播一个 bool 值 : true
var bizDataBoolean = WrapperKit.of(true);
broadcastContext.broadcast(cmdInfo, bizDataBoolean);
// 对象列表演示
DemoBroadcastMessage broadcastMessage = new DemoBroadcastMessage();
broadcastMessage.msg = "broadcast hello," + counter.longValue();
List<DemoBroadcastMessage> list = new ArrayList<>();
list.add(broadcastMessage);
var bizDataList = WrapperKit.ofListByteValue(list);
broadcastContext.broadcast(cmdInfo, bizDataList);
// int 列表
var bizDataIntList = IntValueList.of(List.of(1, 3, 5, 7));
broadcastContext.broadcast(cmdInfo, bizDataIntList);
... ... 省略部分代码
其他类同,不全部介绍了。
}
[#133] 向指定对外服上的用户广播数据
示例参考代码
... ...省略部分代码
private static void extracted(String externalId) {
var bizData = new DemoBroadcastMessage();
broadcastMessage.msg = "broadcast hello!" ;
// 广播消息的路由
CmdInfo cmdInfo = ...;
ResponseMessage responseMessage = BarMessageKit.createResponseMessage(cmdInfo, bizData);
// 指定游戏对外服广播
HeadMetadata headMetadata = responseMessage.getHeadMetadata();
int sourceClientId = MurmurHash3.hash32(externalId);
headMetadata.setSourceClientId(sourceClientId);
// 广播上下文
BroadcastContext broadcastContext = BrokerClientHelper.getBroadcastContext();
broadcastContext.broadcast(responseMessage);
}
容错设置
IoGameGlobalConfig.brokerSniperToggleAK47 = boolean;
Broker(游戏网关)转发消息容错配置
游戏逻辑服与游戏对外服通信时,如果没有明确指定要通信游戏对外服,游戏网关则会将消息转发到所有的游戏对外服上。
如果指定了游戏对外服的,游戏网关则会将消息转发到该游戏对外服上,而不会将消息转发到所有的对外服上。
当为 true 时,开启容错机制
表示开发者在发送消息时,如果指定了游戏对外服的,
但【游戏网关】中没有找到所指定的【游戏对外服】,则会将消息转发到所有的游戏对外服上,
这么做的目的是,即使开发者填错了指定的游戏对外服,也能保证消息可以送达到游戏对外服。
当为 false 时,关闭容错机制
表示在【游戏网关】中找不到指定的【游戏对外服】时,则不管了。
支持的通讯方式场景
广播、推送
获取游戏对外服的数据与扩展
另一种叙述版本
作用:
在游戏逻辑服发送广播时,支持指定游戏对外服来广播;
如果你能事先知道所要广播的游戏对外服,那么在广播时通过指定游戏对外服,可以避免一些无效的转发。
为了更好的理解的这个配置的作用,这里将作一些比喻:
1. 将广播时指定的游戏对外服,看作是目标
2. 将发送广播的游戏逻辑服,看作是命令
3. 而 Broker(游戏网关)职责是对消息做转发,可看成是一名射击员;射击员手上有两把枪,分别是狙击枪和 AK47。
狙击枪的作用是单点目标,而 AK47 的作用则是扫射多个目标(就是所有的游戏对外服)。
场景一:
当设置为 true 时,表示射击员可以将手中的狙击切换为 AK47,什么意思呢?
意思就是如果在【游戏网关】中没有找到所指定的【游戏对外服】,则将广播数据发送给【所有的游戏对外服】。(换 AK 来扫射)
这么做的目的是,即使开发者填错了指定的游戏对外服,也能保证消息可以送达到游戏对外服。
场景二:
当设置为 false 时,表示找不到指定的【游戏对外服】时,则不管了。
[#131] 获取指定对外服上数据的接口
参考使用示例,通过 RequestCollectExternalMessage 请求对象,可以指定游戏对外服id;
@UtilityClass
public class ExternalCommunicationKit {
/**
* 设置元信息到游戏对外服
*
<pre>
* 之后所有 action 的 FlowContext 中会携带上这个元信息对象,
* 不建议在元信息保存过多的信息,因为会每次传递。
* </pre>
*
* @param attachment 元信息
* @param flowContext flowContext
*/
public void setAttachment(Attachment attachment, FlowContext flowContext) {
// 不做 null 判断,只做个 userId 的检测
long userId = attachment.getUserId();
if (userId <= 0) {
throw new RuntimeException("userId <= 0");
}
// 得到游戏对外服 id
RequestMessage request = flowContext.getRequest();
HeadMetadata headMetadata = request.getHeadMetadata();
int sourceClientId = headMetadata.getSourceClientId();
var requestCollectExternalMessage = new RequestCollectExternalMessage()
// 根据业务码,调用游戏对外服与业务码对应的业务实现类 (AttachmentDataExternalBizRegion)
.setBizCode(ExternalBizCodeCont.attachment)
// 元信息
.setData(attachment)
// 指定游戏对外服
.setSourceClientId(sourceClientId);
BrokerClientHelper
// 【游戏逻辑服】与【游戏对外服】通讯上下文
.getInvokeExternalModuleContext()
.invokeExternalModuleCollectMessage(requestCollectExternalMessage);
}
}
容错设置
IoGameGlobalConfig.brokerSniperToggleAK47 = boolean;
网络游戏服务器框架 ioGame 17.1.43 新版游戏对外服
[#115] 游戏对外服增加路由是否存在检测
参考:https://www.yuque.com/iohao/game/ea6geg#EeWiH
新游戏对外服中增加路由存在检测。当路由不存在时,可以起到抵挡的作用,而不必经过其他服务器。
[#114] 支持玩家与多个游戏逻辑服的动态绑定
文档:动态绑定游戏逻辑服
动态绑定游戏逻辑服,指的是玩家与游戏逻辑服绑定后,之后的请求都由该游戏逻辑服来处理。
玩家动态绑定逻辑服节点后,之后的请求都由这个绑定的游戏逻辑服来处理,可以实现类似 LOL、王者荣耀匹配后动态分配房间的效果。
支持玩家与多个游戏逻辑服的动态绑定。
使用场景
跨服活动、跨服战斗等。
动态绑定游戏逻辑服可以解决玩家增量的问题,我们都知道一台机器所能承载的运算是有上限的;当上限达到时,就需要增加新机器来分摊请求量;如果你开发的游戏是有状态的,那么你如何解决请求分配的问题呢?在比如让你做一个类似 LOL、王者荣耀的匹配,将匹配好的玩家分配到一个房间中,之后这些玩家的请求都能在同一个游戏逻辑服上处理,这种业务你该如何实现呢?
使用框架提供的动态绑定逻辑服节点可以轻松解决此类问题,而且还可以根据业务规则,计算出当前空闲最多的游戏逻辑服,并将此游戏逻辑服与玩家做绑定,从而做到均衡的利用机器资源,来防止请求倾斜的问题。
[#113] 新版本游戏对外服
文档:新游戏对外服使用
迁移指南 :迁移到新版游戏对外服
【新版游戏对外服】用于取代【旧的游戏对外服】,如果条件允许,请尽可能做迁移,整体工作量很少。旧的游戏对外服将不在做功能上的新增,如果存在 bug 将会继续修复,维护期会持续到下个大版本前。
从架构简图中,我们知道了整体架构由三部分组成 1.游戏对外服、2.游戏网关、3.游戏逻辑服。本篇将介绍游戏对外服这部分,及功能扩展等相关的。
游戏对外服的职责
- 保持与用户(玩家)长的连接
- 帮助开发者屏蔽通信细节、与连接方式的细节
- 连接方式支持:WebSocket、TCP、UDP
- 将用户(玩家)请求转发到游戏网关
- 可动态增减扩展机器
- 功能扩展,如:路由存在检测、路由权限、UserSession 管理、心跳,及后续要提供但还未提供的熔断、限流、降载、用户流量统计等功能。
扩展场景
游戏对外服主要负责与用户(玩家)的连接。假设一台硬件支持最多建立 5000 个用户连接,当用户量达到 7000 人时,我们可以增加一个游戏对外服来进行流量控制和减压。
由于游戏对外服的扩展性和灵活性,可以支持同时在线玩家从几千人到数千万人不等。这是因为,通过增加游戏对外服的数量,可以有效地进行连接的负载均衡和流量控制,使得系统能够更好地承受高并发的压力。
连接方式的切换、支持、扩展
ioGame 已提供了 TCP、WebSocket、UDP 连接方式的支持,并提供了灵活的方式来实现连接方式的切换。可以将 TCP、WebSocket、UDP 连接方式与业务代码进行无缝衔接。开发者可以用一套业务代码,无需任何改动,同时支持多种通信协议。
如果想要切换到不同的连接方式,只需要更改相应的枚举即可,非常简单。在不使用 ioGame 时,将连接方式从 TCP 改为 WebSocket 或 UDP 等,需要进行大量的调整和改动。然而,在 ioGame 中,实现这些转换是非常简单的。此外,不仅可以轻松切换各种连接方式,而且可以同时支持多种连接方式,并使它们在同一应用程序中共存。
连接方式是可扩展的,而且扩展也简单,这意味着之后如果支持了 KCP,那么将已有项目的连接方式,如 TCP、WebSocket、UDP 切换成 KCP 也是简单的。
需要再次强调的是,连接方式的切换对业务代码没有任何影响,无需做出任何改动即可实现连接方式的更改。
新游戏对外服 - UML
游戏对外服由两部分构成
- ExternalCore:与真实玩家连接的 ExternalCore 服务器
- ExternalBrokerClientStartup:负责内部通信,与 Broker(游戏网关)通信
我们只需要关注 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>
Netty 游戏服务器框架 ioGame 17.1.42 集群增强
[#127] 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] 集群重启后组网异常
导致集群数量对不上,触发的事件顺序可能是 ADDED、REMOVED,也可能是REMOVED、ADDED,现已修复。
其他更新
<scalecube-cluster.version>2.6.14</scalecube-cluster.version>
框架整体预览导图
ioGame 简介
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 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 来打造自己的游戏服务器。
java 游戏服务器框架 ioGame 17.1.40 脉冲通讯
[#99] 增加 msgId 特性,默认只在 request/response 通讯方式下生效
游戏前端可以给游戏对外服协议添加一个 msgId,当 ioGame 接收到请求并处理完请求后,会在响应时将 msgId 回传给请求端;类似透传参数。
[#102] 业务框架 BarSkeleton 类增加动态属性,方便扩展.
[#111] 新增文档解析、文档生成的控制选项
在 windows 系统下开发时,如果 action 类过多,可能会导致启动慢;类 Linux 系统没有此问题,框架增加两个设置,可以让开发者决定是否启用相关功能。
public class DemoLogicServer extends AbstractBrokerClientStartup {
... ... 省略部分代码
@Override
public BarSkeleton createBarSkeleton() {
// 业务框架构建器
BarSkeletonBuilder builder = ...;
BarSkeletonSetting setting = builder.getSetting();
// 不生成文档
setting.setGenerateDoc(false);
// 不解析文档
setting.setParseDoc(false);
...
return builder.build();
}
}
[#103] 业务框架新增 Runner 机制,增强扩展性、规范性
详细的使用文档:Runner 机制 - 文档
Runner 机制类似于 Spring CommandLineRunner 的启动项,它能够在逻辑服务器启动之后调用一次 Runner 接口实现类,让开发者能够通过实现 Runner 接口来扩展自身的系统。
使用 Runner 机制,开发者可以通过扩展已有模块的功能或提供配置相关的功能来实现自定义扩展。
Runner 机制不仅可以让我们将已有模块的功能以 Runner 形式进行扩展,也可以通过 Runner 机制来提供配置相关的功能,避免配置过于零散。
事实上,Runner 机制的可扩展性远远不止于此。通过 onStart 方法中的业务框架对象 BarSkeleton,开发者可以实现相关隔离并利用其动态属性来扩展特殊业务数据。一个业务框架对象对应一个逻辑服。
[#104] 新增实验性特性-脉冲通讯方式
详细的使用文档:脉冲通讯方式-文档
脉冲通讯与发布订阅类似,但是它除了具备发布订阅的无需反馈的方式,还增加了接收消息响应的动作,这是它与发布订阅的重要区别。
需要注意的是,脉冲通讯只是一种通讯方式,不能完全取代发布订阅,而是适用于一些特殊的业务场景。虽然在理论上,这些特殊的业务场景可以使用发布订阅来完成,但这会让代码变得复杂。
脉冲通讯在特定的场景下有巨大的优势!关于脉冲通讯更多的应用场景发挥,如同业务框架插件一样,取决于开发者的想象力。
注意事项
开源协议更改为 GPL2.0
其他更新
BrokerClient 添加 AwareInject
<netty.version>4.1.92.Final</netty.version>
<jctools-core.version>4.0.1</jctools-core.version>
<qdox.version>2.0.3</qdox.version>
<protobuf-java.version>3.22.4</protobuf-java.version>
框架整体预览导图
ioGame 简介
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络游戏服务器框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。
ioGame 是一个 java 网络游戏服务器框架,有以下特点:
- 无锁异步化、事件驱动的架构设计
- 支持 websocket 和 socket 两种通信协议
- 支持 protobuf、json 等不同的通信协议
- 集群无中心节点、集群自动化、分布式的设计
- 轻量级,不依赖第三方中间件或数据库就能支持集群、分布式
- 提供多种通讯方式,且逻辑服之间可以相互跨机器通信
- 与 spring 和其他框架融合方便
- 学习成本低,开发体验好
- 支持多服单进程、多服多进程的启动和部署方式
- 提供游戏文档生成的辅助功能
- 包体小、启动快、内存占用少
- 提供优雅的路由访问权限控制
- 提供了灵活的线程扩展、设置
ioGame 是一个专为网络游戏服务器设计的轻量级框架,它可以帮助你快速地搭建和运行自己的游戏服务器。它适用于各种类型和规模的网络游戏,无论是 H5、手游还是 PC 游戏,无论是简单的聊天室,还是复杂的全球同服、回合制游戏、策略游戏、放置休闲游戏、即时战斗、MMORPG 等,ioGame 都可以满足你的需求。
ioGame 在打包、内存占用、启动速度等方面也是优秀的。打 jar 包后大约 15MB,应用通常会在 0.x 秒内完成启动,内存占用小。详细请看 快速从零编写服务器完整示例。
在生态融合方面,ioGame 可以很方便的与 spring 集成(5 行代码);除了 spring 外,还能与任何其他的框架做融合,从而使用其他框架的相关生态。
在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架,而无需在安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf协议编译工具 ... ...等。
在通讯方式方面,大部分框架只能支持推送(广播)这一类型的通讯方式;而 ioGame 则提供了 3 种类型的通讯方式,分别是推送、单次请求处理、逻辑服之间相互通信。其中逻辑服之间相互通信,除了可以让我们跨机器通信外,还能与同类型多个游戏逻辑服同时通信并得到结果;
在通信方面,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 来打造自己的游戏服务器。
轻量级游戏服务器框架 ioGame 17.1.38 发布
主要更新
#46 action 业务参数与返回值增加 List 支持
使用文档 https://www.yuque.com/iohao/game/ieimzn#Aqc1C
action 支持 List 参数与返回值,可以有效的减少协议碎片、减少工作量等。在没有支持 List 之前的代码,如果想要传输一个列表的数据,通常需要将 pb 对象包装到另一个 pb 响应对象中。
让我们先看一个示例,这个示例中 action 方法的的逻辑很简单,将查询到的数据列表给到请求端。由于之前不支持 List 返回值,开发者想要将列表中的数据给到请求端,还需要额外的定义一个与之对应的响应类,只有这样才能将列表数据给到请求端。
我们可以想象一下,如果你的系统中有很多固定的配置数据,比如装备、道具、活动信息、英雄人物介绍、敌人相关信息、地图信息、技能信息、宠物基本信息...等等,通常会有几十、上百个这样的响应对象。
为了将这些固定的配置数据给到请求端,而建立与之对应的响应对象,想想这是一件多么无聊的一件事情。这些多出来的响应对象,就是协议碎片,是一种可有可无的协议;此外还有如下缺点:
- 将会变成干扰项
- 增加维护成本
- 增加工作量(每次有新的配置表都要新建、在每个 action 中,都要创建这个响应对象)
不使用 List 时的写法
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Animal {
/** id */
int id;
}
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class AnimalResponse {
List<Animal> animals;
}
@ActionController(3)
public class HallAction {
@ActionMethod(10)
public AnimalResponse listAnimal1() {
// 查询出列表
var list = IntStream.range(1, 4).mapToObj(id -> {
Animal animal = new Animal();
animal.id = id;
return animal;
}).collect(Collectors.toList());
// 将列表存放到 Animal 的响应对象中
AnimalResponse animalResponse = new AnimalResponse();
animalResponse.animals = list;
return animalResponse;
}
}
通过上面的介绍,知道协议碎片是多么恐怖的一件事了把。其实我们的需求也很简单,只是想把列表中的数据给到请求端就可以了。此时,我们可以利用 action 将列表数据通过 List 直接返回,这样可以避免上面所说的各种缺点。同时,还可以让我们的代码更加的简洁,这种方式可以使前端与后端都受益。
用更少的代码实现了同样的功能,减少了工作量,避免了协议碎片。这样,开发者就不在需要额外的建立一个与之对应的响应协议了;当使用了框架提供的 List 返回值后,可以帮助你的系统减少几十、上百个类似 xxxResponse 的协议。
来,让我们看看修改后的代码是有多么简洁的吧。这种编码方式,即使你是一个新手,也能快速的看懂;
Action 使用 List 返回数据
@ActionController(3)
public class HallAction {
@ActionMethod(9)
public List<Animal> listAnimal() {
// 查询出列表
return IntStream.range(1, 4).mapToObj(id -> {
Animal animal = new Animal();
animal.id = id;
return animal;
}).collect(Collectors.toList());
}
}
原理
ioGame 在游戏对外服的协议中,提供了一个公共的 message,用于存放 List 数据。
// pb 对象 list 包装类
message ByteValueList {
// pb 对象 List、pb 对象 Array
repeated bytes values = 1;
}
游戏对外服协议请看:https://www.yuque.com/iohao/game/zfg3ci 。
#79 light-jprotobuf 模块支持枚举
生成的 PB 文件
// 动物
message Animal {
// id
int32 id = 1;
// 动物类型 - 枚举测试
AnimalType animalType = 2;
}
// 动物类型
enum AnimalType {
// 鸟
BIRD = 0;
// 猫
CAT = 1;
}
#84 生成proto文件时,内容的顺序总是产生变化
实际使用过程中发现一个问题如下:当协议没有任何变化时,生成的协议文件依然会产生顺序变化。
例如:当前的协议定义有 A,B,C 三个类。如果对协议进行多次生成,产生的proto文件内的定义顺序可能是:A,C,B 或者 B,C,A。
标记废弃的
将 IoGameGlobalSetting�.me() 方法标记为废弃的,将 IoGameGlobalSetting 内的方法改为静态的。
其他更新
<netty.version>4.1.91.Final</netty.version>
优化文档生成、控制台打印。
ExternalMessage.proto 新增 message ByteValueList,用于接收与发送 List 类型的数据
... 省略部分代码
// pb 对象 list 包装类
message ByteValueList {
// pb 对象 List、pb 对象 Array
repeated bytes values = 1;
}
注意事项
此版本在游戏对外服协议中新增了 message ByteValueList 来支持 action 返回 List 类型,因此需要前端同学同步一下协议文件。
对外服的协议说明: https://www.yuque.com/iohao/game/xeokui
ioGame 简介
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络游戏服务器框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。
ioGame 是一个 java 网络游戏服务器框架,有以下特点:
- 无锁异步化、事件驱动的架构设计
- 支持 websocket 和 socket 两种通信协议
- 支持 protobuf、json 等不同的通信协议
- 集群无中心节点、集群自动化、分布式的设计
- 轻量级,不依赖第三方中间件或数据库就能支持集群、分布式
- 提供多种通讯方式,且逻辑服之间可以相互跨机器通信
- 与 spring 和其他框架融合方便
- 学习成本低,开发体验好
- 支持多服单进程、多服多进程的启动和部署方式
- 提供游戏文档生成的辅助功能
- 包体小、启动快、内存占用少
- 提供优雅的路由访问权限控制
- 提供了灵活的线程扩展、设置
ioGame 是一个专为网络游戏服务器设计的轻量级框架,它可以帮助你快速地搭建和运行自己的游戏服务器。它适用于各种类型和规模的网络游戏,无论是 H5、手游还是 PC 游戏,无论是简单的聊天室,还是复杂的全球同服、回合制游戏、策略游戏、放置休闲游戏、即时战斗、MMORPG 等,ioGame 都可以满足你的需求。
ioGame 在打包、内存占用、启动速度等方面也是优秀的。打 jar 包后大约 15MB,应用通常会在 0.x 秒内完成启动,内存占用小。详细请看 快速从零编写服务器完整示例。
在生态融合方面,ioGame 可以很方便的与 spring 集成(5 行代码);除了 spring 外,还能与任何其他的框架做融合,从而使用其他框架的相关生态。
在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架,而无需在安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf协议编译工具 ... ...等。
在通讯方式方面,大部分框架只能支持推送(广播)这一类型的通讯方式;而 ioGame 则提供了 3 种类型的通讯方式,分别是推送、单次请求处理、逻辑服之间相互通信。其中逻辑服之间相互通信,除了可以让我们跨机器通信外,还能与同类型多个游戏逻辑服同时通信并得到结果;
在通信方面,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 来打造自己的游戏服务器。
Netty 游戏服务器框架 ioGame 17.1.37 发布
主要更新
UserProcessor 如果自身提供了 Executor ,将不会使用框架的 Executor 创建策略。
调整 DefaultUserProcessorExecutorStrategy 创建参数。
DebugInOut 增加当前执行业务的线程名打印
┏━━━━━ Debug. [(DemoAction.java:44).here] ━━━ [cmd:1 - subCmd:0 - cmdMerge:65536] ━━━ [逻辑服 [demo游戏逻辑服] - id:[6c13900c-15cd-4173-adfc-8b922a0d271f]]
┣ userId: 0
┣ 参数: helloReq : HelloReq{name='塔姆'}
┣ 响应: HelloReq{name='塔姆, I'm here '}
┣ 时间: 7 ms (业务方法总耗时)
┗━━━━━ Debug [DemoAction.java - ioGame:17.1.37] ━━━━━━━━━━━━━ [执行线程:RequestMessage-11-1]
[#77] RequestMessageClientProcessorHook 提供新的默认实现 DefaultRequestMessageClientProcessorHook,通过 userId 取得对应的线程来处理业务逻辑,避免并发问题;
重新编写 ioGame 线程相关的文档。详细的介绍了网络部分的线程及扩展、业务框架部分的线程及扩展;单玩家如何避免多线程并发的、同一房间内多个玩家如何避免多线程并发的。
其他更新
<netty.version>4.1.90.Final</netty.version>
- 无锁异步化、事件驱动的架构设计;轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式
- 通过 ioGame 可以很容易的搭建出一个集群无中心节点、集群自动化、多进程的分步式游戏服务器
- 包体小、启动快、内存占用少、更加的节约、无需配置文件、提供了优雅的路由访问权限控制
- 让开发者用一套业务代码,无需任何改动,同时支持多种通信协议:WebSocket、TCP
- 让开发者用一套业务代码,能轻松切换和扩展不同的通信协议:Protobuf、JSON
- 近原生的性能;业务框架在单线程中平均每秒可以执行 1152 万次业务逻辑
- 代码即联调文档、JSR380验证、断言 + 异常机制 = 更少的维护成本
- 在业务开发中,提供了业务逻辑的执行信息、代码定位与跳转等
- 架构部署灵活性与多样性:既可相互独立,又可相互融合
- 可同时与同类型的多个游戏逻辑服通信并得到数据
- 逻辑服之间可相互跨进程、跨机器进行通信
- 支持玩家对游戏逻辑服进行动态绑定
- 能与任何其他框架做融合共存
- 对 webMVC 开发者友好
- 无 spring 强依赖
- 零学习成本
ioGame 简介
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络游戏服务器框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。
ioGame 是一个 java 网络游戏服务器框架,有以下特点:
- 无锁异步化、事件驱动的架构设计
- 支持 websocket 和 socket 两种通信协议
- 支持 protobuf、json 等不同的通信协议
- 集群无中心节点、集群自动化、分布式的设计
- 轻量级,不依赖第三方中间件或数据库就能支持集群、分布式
- 提供多种通讯方式,且逻辑服之间可以相互跨机器通信
- 与 spring 和其他框架融合方便
- 学习成本低,开发体验好
- 支持多服单进程、多服多进程的启动和部署方式
- 提供游戏文档生成的辅助功能
- 包体小、启动快、内存占用少
- 提供优雅的路由访问权限控制
- 提供了灵活的线程扩展、设置
ioGame 是一个专为网络游戏服务器设计的轻量级框架,它可以帮助你快速地搭建和运行自己的游戏服务器。它适用于各种类型和规模的网络游戏,无论是 H5、手游还是 PC 游戏,无论是简单的聊天室,还是复杂的全球同服、回合制游戏、策略游戏、放置休闲游戏、即时战斗、MMORPG 等,ioGame 都可以满足你的需求。
ioGame 在打包、内存占用、启动速度等方面也是优秀的。打 jar 包后大约 15MB,应用通常会在 0.x 秒内完成启动,内存占用小。详细请看 快速从零编写服务器完整示例。
在生态融合方面,ioGame 可以很方便的与 spring 集成(5 行代码);除了 spring 外,还能与任何其他的框架做融合,从而使用其他框架的相关生态。
在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架,而无需在安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf协议编译工具 ... ...等。
在通讯方式方面,大部分框架只能支持推送(广播)这一类型的通讯方式;而 ioGame 则提供了 3 种类型的通讯方式,分别是推送、单次请求处理、逻辑服之间相互通信。其中逻辑服之间相互通信,除了可以让我们跨机器通信外,还能与同类型多个游戏逻辑服同时通信并得到结果;
在通信方面,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 来打造自己的游戏服务器。
Java Netty 游戏服务器框架 ioGame 17.1.35 发布
移除废弃的 UserProcessor ChangeUserIdMessageBrokerSyncProcessor
[#62] RequestMessageClientProcessor 中的 FlowContext 增加路由、响应对象、用户id 相关的属性设置。
UserProcessor DefaultUserProcessorExecutorStrategy 用户线程池策略变更:
UserProcessor RequestMessageClientProcessor 请求处理单独一个池
其他的 UserProcessor 共用一个池
领域事件部分代码整理
将 BrokerClientHelper.me() 标记为 Deprecated
请使用 BrokerClientHelper 的静态方法,如 BrokerClientHelper.me().xxx() 改为 BrokerClientHelper.xxx()
- 无锁异步化、事件驱动的架构设计;轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式
- 通过 ioGame 可以很容易的搭建出一个集群无中心节点、集群自动化、多进程的分步式游戏服务器
- 包体小、启动快、内存占用少、更加的节约、无需配置文件、提供了优雅的路由访问权限控制
- 让开发者用一套业务代码,无需任何改动,同时支持多种通信协议:WebSocket、TCP
- 让开发者用一套业务代码,能轻松切换和扩展不同的通信协议:Protobuf、JSON
- 近原生的性能;业务框架在单线程中平均每秒可以执行 1152 万次业务逻辑
- 代码即联调文档、JSR380验证、断言 + 异常机制 = 更少的维护成本
- 在业务开发中,提供了业务逻辑的执行信息、代码定位与跳转等
- 架构部署灵活性与多样性:既可相互独立,又可相互融合
- 可同时与同类型的多个游戏逻辑服通信并得到数据
- 逻辑服之间可相互跨进程、跨机器进行通信
- 支持玩家对游戏逻辑服进行动态绑定
- 能与任何其他框架做融合共存
- 对 webMVC 开发者友好
- 无 spring 强依赖
- 零学习成本
ioGame 简介
你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分步式的网络游戏服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络游戏服务器框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。
ioGame 是一个 java 网络游戏服务器框架,有以下特点:
- 无锁异步化、事件驱动的架构设计
- 支持 websocket 和 socket 两种通信协议
- 支持 protobuf、json 等不同的通信协议
- 集群无中心节点、集群自动化、分布式的设计
- 轻量级,不依赖第三方中间件或数据库就能支持集群、分布式
- 提供多种通讯方式,且逻辑服之间可以相互跨机器通信
- 与 spring 和其他框架融合方便
- 学习成本低,开发体验好
- 支持多服单进程、多服多进程的启动和部署方式
- 提供游戏文档生成的辅助功能
- 包体小、启动快、内存占用少
- 提供优雅的路由访问权限控制
ioGame 是一个专为网络游戏服务器设计的轻量级框架,它可以帮助你快速地搭建和运行自己的游戏服务器。它适用于各种类型和规模的网络游戏,无论是 H5、手游还是 PC 游戏,无论是简单的聊天室,还是复杂的全球同服、回合制游戏、策略游戏、放置休闲游戏、即时战斗、MMORPG 等,ioGame 都可以满足你的需求。
ioGame 在打包、内存占用、启动速度等方面也是优秀的。打 jar 包后大约 15MB,应用通常会在 0.x 秒内完成启动,内存占用小。详细请看 快速从零编写服务器完整示例。
在生态融合方面,ioGame 可以很方便的与 spring 集成(5 行代码);除了 spring 外,还能与任何其他的框架做融合,从而使用其他框架的相关生态。
在轻量级方面,ioGame 不依赖任何第三方中间件或数据库就能支持集群、分布式,只需要 java 环境就可以运行。这意味着在使用上简单了,在部署上也为企业减少了部署成本、维护难度。使用 ioGame 时,只需一个依赖即可获得整个框架,而无需在安装其他服务,如: Nginx、Redis、MQ、Mysql、ZooKeeper、Protobuf协议编译工具 ... ...等。
在通讯方式方面,大部分框架只能支持推送(广播)这一类型的通讯方式;而 ioGame 则提供了 3 种类型的通讯方式,分别是推送、单次请求处理、逻辑服之间相互通信。其中逻辑服之间相互通信,除了可以让我们跨机器通信外,还能与同类型多个游戏逻辑服同时通信并得到结果;
在通信方面,ioGame 让开发者用一套业务代码,同时支持 WebSocket 和 TCP 两种通信协议,无需做任何改动。这意味着一个游戏服务器可以同时接入 WebSocket 和 TCP 的游戏客户端。
在通信协议方面,ioGame 让开发者用一套业务代码,就能轻松切换和扩展不同的通信协议,如 Protobuf、JSON 等。只需一行代码,就可以从 Protobuf 切换到 JSON,无需改变业务方法。
在集群方面,ioGame 的 Broker (游戏网关)采用无中心节点、自动化的集群设计,所有节点平等且自治,不存在单点故障。集群能够自动管理和弹性扩缩,节点加入或退出时,能够自动保证负载均衡和数据一致性,不影响服务可用性。
在分布式方面,ioGame 的逻辑服使用了分布式设计思想,将服务器分为游戏对外服、游戏逻辑服等不同层次,并且每一层都有明确的职责和接口。这样可以提高代码可读性和可维护性,并且方便进行水平扩展。
在学习成本方面,ioGame 的学习成本非常低,可以说是零学习成本,即使没有游戏编程经验,也能轻松上手。开发者只需掌握普通的 java 方法或 webMVC 相关知识,就能用框架开发业务。框架不要求开发者改变编码习惯,而是自身适应开发者的需求。
在开发体验方面,ioGame 非常注重开发者的开发体验;框架提供了 JSR380验证、断言 + 异常机制、业务代码定位... ...等诸多丰富的功能,使得开发者的业务代码更加的清晰、简洁;
在分布式开发体验方面,通常在开发分布式应用时是需要启动多个进程的。这会让调试与排查问题变得非常困难,从而降低开发者的效率、增加工作量等,这也是很多框架都解决不了的问题,但 ioGame 做到了!ioGame 支持多服单进程的启动方式,这使得开发者在开发和调试分步式系统时更加简单。
与前端对接联调方面,ioGame 提供了游戏文档生成的辅助功能,可以做到代码即对接文档。简单地说,当业务代码编写完后,框架会自动生成最新的文档。如果没有游戏文档的生成,那么你将要抽出一些时间来编写、维护对接文档的工作,而且当团队人数多了之后,文档就会很乱、不同步、不是最新的、忘记更新等情况就会出现。
在部署方面,ioGame 支持多服单进程的方式部署,也支持多服多进程多机器的方式部署;在部署方式上可以随意的切换而不需要更改代码。日常中我们可以按照单体思维开发,到了生产可以选择使用多进程的方式部署。
开发者基于 ioGame 编写的项目模块,通常是条理清晰的,得益于框架对路由的合理设计,同时也为路由提供了优雅的访问权限控制。当我们整理好这些模块后,对于其他开发者接管项目或后续的维护中,会是一个不错的帮助(模块的整理与建议)。或许现阶段你感受不到这块的威力,随着你深入地使用实践就能体会到这么设计的诸多好处与优势。
开发者基于 ioGame 编写的项目,通常是语法简洁的、高性能的、低延迟的;框架最低要求使用 JDK17,这样即可以让项目享受到 ZGC 带来的改进,还能享受语法上的简洁。从 JDK17 开始 ZGC 远低于其亚毫秒级暂停时间的目标,可以在不影响游戏速度的情况下,清理掉多余的内存。这样就不会出现卡顿或者崩溃的问题了,相当于在项目中变相的引入了一位 JVM 调优大师,详细请看 JDK 17 垃圾回收 GC 性能飞跃提升。
综上所述,ioGame 是一个非常适合网络游戏开发的框架。可以让你轻松地创建高性能、低延迟、易扩展的游戏服务器,并且节省时间和资源。如果你想要快速地开发出令人惊艳的网络游戏,请不要犹豫,立即选择 ioGame 吧!框架屏蔽了很多复杂且重复性的工作,并可为项目中的功能模块结构、开发流程等进行清晰的组织定义,减少了后续的项目维护成本。
相信你已经对 ioGame 有了一个初步的了解,虽然还有很多丰富的功能与特性没有介绍到,但你可以通过后续的实践过程中来深入了解。感谢你的阅读,并期待你使用 ioGame 来打造自己的游戏服务器。
Netty 分布式游戏服务器框架 ioGame 17.1.34 发布 路由访问权限增强
[#47] 增加拒绝外部直接访问 action 的路由权限
有些 action 只能内部访问,比如增加金币、敏感数值的增加等。这些 action 是不能由外部直接访问的,这里说的外部指的连接的玩家。
// 拒绝主路由为 10 的访问请求
ExternalGlobalConfig.accessAuthenticationHook.addRejectionCmd(10);
// 拒绝主路由为 11、子路由为 1 的访问请求
ExternalGlobalConfig.accessAuthenticationHook.addRejectionCmd(11, 1);
从上面代码中我们可以看见访问接口提供了两个方法,一个用于范围路由控制的,一个用于精准路由控制的,这样这样对应的路由将不能由外部的真实玩家直接访问。
参考文档:路由访问权限控制
[#45] 游戏对外服独立 UserSession 管理部份逻辑
[#54] 动态属性接口增加消费操作
如果动态属性存在,则使用该值执行给定操作,否则不执行任何操作。
public interface AttrOptionDynamic {
... 省略部分代码
/**
* 如果动态属性存在,则使用该值执行给定操作,否则不执行任何操作。
*
* @param option option
* @param consumer 只有 option 的值存在且不为 null 时,则要执行的动作
* @param <T> t
*/
default <T> void ifPresent(AttrOption<T> option, Consumer<T> consumer) {
T data = this.option(option);
if (Objects.nonNull(data)) {
consumer.accept(data);
}
}
}
废弃
将 ExternalBizHandler 标记为废弃,由 UserSessionHandler、AccessAuthenticationHandler、RequestBrokerHandler 三个 Handler 代替,这样更符合单一职责。
其他更新
<netty.version>4.1.89.Final</netty.version>
支持基础类型装箱、拆箱,集群自动化 Netty 游戏服务器框架 ioGame 17.1.33
action 业务参数自动装箱、拆箱增强。
支持 action 接收与返回基础类型:int、long、boolean 和字符串 String。
支持 action 接收与返回多个基础类型:List、List、List 和 List
关于 action 业务参数、返回值的自动装箱、拆箱更详细的使用文档,可以参考:业务参数自动装箱、拆箱基础类型
[#39] 新增业务参数自动装箱、拆箱"基础"类型-String
使用示例,action 参数与返回值支持 String 类型
@ActionController(6)
public class StringAction {
@ActionMethod(30)
public String string2string(String s) {
return s + 1;
}
}
String 类型在 action 方法中的参数与返回值还可以使用 List 。
@ActionController(6)
public class StringAction {
@ActionMethod(32)
public List<String> stringList2stringList(List<String> stringList) {
List<String> list = new ArrayList<>();
list.add(11L + "");
list.add(22L + "");
return list;
}
}
[#38] 新增业务参数自动装箱、拆箱基础类型-boolean
使用示例与 String 示例类似
[#42] 新增业务参数自动装箱、拆箱基础类型-int
使用示例与 String 示例类似
[#43] 新增业务参数自动装箱、拆箱基础类型-long
使用示例与 String 示例类似
修复 ExternalServerBuilder.channelPipelineHook 设置业务编排钩子接口被默认实现覆盖的问题
【废弃与替换】
标记废弃 IntPb ,由 IntValue 代替
标记废弃 IntListPb ,由 IntValueList 代替
标记废弃 LongPb ,由 LongValue 代替
标记废弃 LongListPb ,由 LongValueList 代替
废弃原因-1:属性名称不统一
废弃原因-2:命名以 pb 结尾,这会导致在使用非 pb 协议时,会产生歧义
不兼容说明
如果开发者在之前的版本中的 action 使用的是 int、long 作为接收与返回参数的,此次版本不会有兼容问题。
如果使用的是 IntPb、IntListPb、LongPb、LongListPb 将会有不兼容的情况,因为当前版本已将 int、long 基础类型装箱、拆箱的类型解析器,替换为新版本的解析器。
如果想兼容旧版本的,可以通过下面的代码来做兼容。如果条件允许,请使用新版本,因为这得到了统一。
MethodParsers.tempCompatibility();
注意:由于此版本更新了 pb 原文件,需要前端同学重新生成一次协议。pb 原文件可查看:对外服协议说明。
理论上前端不做更改问题也不大,只是生成的对接文档上有差异,如果后端使用了基础类型做接收参数或返回值的,原 IntPb 由 IntValue 代替,原 LongPb 由 LongValue 代替。
其次影响是如果将来打算换成 json 协议来对接,会导致不兼容的情况,如果条件允许,请前端同学尽早做变更。
包体小、内存占用小、启动仅需 0.3 秒的 Netty 游戏服务器框架 ioGame 17.1.31
#37
缩小打包后的包体大小,ioGame 打 jar 包后大约 15MB,演示查看 快速从零编写服务器完整示例。
#36 增加 Banner 打印版本、内存占用、启动耗时等信息。
ioGame 在内存占用、启动速度、打包等方面也是优秀的。
- 内存方面:内存占用小。
- 启动速度方面:应用通常会在 0.x 秒内完成启动。
- 打包方面:打 jar 包后大约 15MB ,详细请看 快速从零编写服务器完整示例。
#34 日志模块增加
用于将框架日志单独存放,与开发者项目的日志分离。
日志支持 log4j2、logback
#I6BE6J
MethodParsers 增加 action 参数解析器的默认设置
#I6C0UF
业务参数自动装箱、拆箱基础类型增强
#I6B76X
修复广播的数据为空时,广播虽然是成功的,但是打印广播日志报错的问题
移除一些第三方库
为缩小打包,将 hutool 依赖移除、将 fastjson2 依赖配置中的 scope 改为 provided;如有使用到相关的,需要开发者自行引入。
移除项目中 json 相关的类文件 ToJson。
如果你的项目中有使用到 hutool 、fastjson2 的,需要在 pom 中添加
cn.hutool hutool-all 5.8.11 com.alibaba.fastjson2 fastjson2 2.0.23其他更新
<netty.version>4.1.87.Final</netty.version>