ioGame 是一个由 java 语言编写的网络游戏服务器框架。支持 websocket、tcp ,适用于回合制游戏、策略游戏、即时战斗游戏,等游戏服务器的开发。具有高性能、稳定、易用易扩展、超好编程体验等特点。可做为 H5(HTML5)、手游、端游的游戏服务器。
在 ioGame 中能让你遗忘 Netty,你几乎没有机会能直接的接触到 Netty 的复杂,但却能享受 Netty 带来的高性能。对开发者要求低,为开发者节约开发时间。
ioGame 可以很方便的与 spring 集成。支持多服多进程的方式部署,也支持多服单进程的方式部署。图中的每个对外服、每个游戏逻辑服、每个 broker (游戏网关)都可以在单独的进程中部署,逻辑服之间可以跨进程通信(对外服也是逻辑服的一种)。
过去、现在、将来都不会有商业版本,所有功能全部开源
只做真的完全式开源,拒绝虚假开源,售卖商业版,不搞短暂维护
承诺项目的维护周期是十年起步, 2022-03-01起,至少十年维护期
提供高质量的使用文档
开源地址: ioGame 网络游戏框架-源码
在线文档::ioGame 网络游戏框架-文档
愿景
让网络游戏服务器的编程变得轻松简单!
架构简图
通过 ioGame 你可以很容易的搭建出一个集群、分步式的网络游戏服务器!
游戏网关集群
broker (游戏网关)可以集群的方式部署,集群无中心节点、自带负载均衡。ioGame 本身就包含服务注册,你不需要外接一个服务注册中心,如 Eureka,ZooKeeper 等(变相的节约服务器成本)。
通过 broker (游戏网关) 的介入,之前非常复杂的负载均衡设计,如服务注册、健康度检查(后续版本提供)、到服务端的连接维护等这些问题,在 ioGame 中都不需要了,结构也简单了很多。
实际上单台 broker (游戏网关) 性能已经能够满足了,因为游戏网关只做了转发。
逻辑服
对外服和游戏逻辑服可以有很多个,逻辑服数量的理论上限是 netty 的连接上限。
ioGame 支持的通信方式
ioGame 支持 3 种类型的通讯方式,分别是单次请求处理、推送、逻辑服间的相互通信;下面分别对这 3 种类型的通讯方式的使用上举几个例子。
1.单次请求处理
1.1 请求、无响应
当请求端发起请求后,逻辑服不会发送任何响应给请求端。可以用在在网络通讯中,存在着不需要接收方回执确认的调用模型,如数据采集的场景: 打点采集、日志传输、metrics上报等。
1.2 请求、响应
请求、响应是在游戏开发中常见的通讯模式,也就是通讯的一方发出请求,而远程通讯的对方做出响应,也就是常说的请求/响应模式。
比如:装备的升级、人物的升级、玩家的移动、抽奖、游戏前端到某一个场景时需要从游戏服务端获取一些对应的场景配置等;
2.推送
2.1 指定单个或多个用户广播(推送)
向一个或多个指定的用户(玩家)主动发送一些数据。 比如:
给指定的在线玩家发送一些奖励。
给在同一个房间内的玩家广播一些数据,如某一个玩家射击子弹,把这子弹的数据广播给房间内的其他玩家。如几个玩家在同一个房间内打牌,某个玩家出牌后,把这张牌的数据广播给房间内的其他玩家。
2.2 全服广播(推送)
给全服的所有在线玩家广播消息,如广播公告、即将停服维护等。
3.逻辑服间的相互通信
3.1 单个逻辑服与单个逻辑服通信请求(可跨进程)
逻辑服与逻辑服之间的相互请求通信
比如:我们有两个游戏逻辑服,分别是:a.天气预报逻辑服、b.战斗逻辑服。现在我们设想一个回合制游戏的战斗场景,需要配合天气,根据天气来增强或者减弱某个英雄的能力。那么在战斗开始前,战斗逻辑服只需要向游戏网关发起一个获取当前天气的请求,就可以得到当前的天气信息了,在根据当前的天气数据来增强或减弱该英雄的能力。
又比如:a.大厅逻辑服、b.奖励发放逻辑服。大厅记录着一些数据(房间总数),奖励发放逻辑服根据当前的房间数量,来生成不同奖品,随机发放给在线用户。
详细示例可参考:逻辑服与逻辑服之间的交互示例
3.2 单个逻辑服与同类型多个逻辑服通信请求(可跨进程)
比如:象棋逻辑服有 3 台, 每台逻辑服都有一个唯一的 逻辑服 id;我们可以在大厅逻辑服中向同类型的多个游戏逻辑服通信请求(可跨进程),意思是大厅发起一个向这 3 台象棋逻辑服的请求,框架会聚合 3个结果集,(假设结果是:当前服务器房间数)当大厅得到这个结果集,我们可以选择房间最少人的象棋逻辑服,假设 《象棋逻辑服-1》 是房间数最少的,我们就可以把逻辑服 id 给到玩家所在的对外服,让玩家在对外服记录下来,之后这个玩家发起的请求就会自动的到 《象棋逻辑服-1》 这台服务器上,不会把请求分配到其他的象棋逻辑服上。
最后,发挥你的想象力,把这 3 类通讯方式用活,可以满足很多业务。
网络游戏框架简介
ioGame 是国内首个基于蚂蚁金服 sofa-bolt 的网络游戏框架,游戏框架由 [网络通信框架] 和 [业务框架] 组成。
- 网络通信框架:负责服务器之间的网络通信
- 业务框架:负责业务逻辑的处理方式和编写方式
通过 ioGame 可以快速的搭建一个稳定的、高性能的、分步式的网络游戏服务器。
broker (游戏网关)可以集群的方式部署,集群无中心节点、自带负载均衡。
游戏框架借助于蚂蚁金服 sofa-bolt 通信框架来提供稳定、高性能。
即使之前没有游戏编程的经验,也能参与到游戏编程中。如果你之前具备一些游戏开发或者 web MVC 相关的知识,则会更容易上手游戏服务器的开发。
源码内置了一个坦克射击游戏的示例,可直接运行。
坦克射击游戏是基于FXGL引擎(纯java的游戏引擎)开发的。
通过示例,可以快速的掌握网络游戏编程!
网络通信框架 - SOFABolt
SOFABolt 是蚂蚁金融服务集团开发的一套基于 Netty 实现的网络通信框架。
- 为了让 Java 程序员能将更多的精力放在基于网络通信的业务逻辑实现上,而不是过多的纠结于网络底层 NIO 的实现以及处理难以调试的网络问题,Netty 应运而生。
- 为了让中间件开发者能将更多的精力放在产品功能特性实现上,而不是重复地一遍遍制造通信框架的轮子,SOFABolt 应运而生。
Bolt 名字取自迪士尼动画-闪电狗,是一个基于 Netty 最佳实践的轻量、易用、高性能、易扩展的通信框架。
业务框架
如果说 sofa-bolt 为了让 Java 程序员能将更多的精力放在基于网络通信的业务逻辑实现上。而业务框架正是解决业务逻辑如何方便的实现这一问题上。
业务框架是游戏框架的一部份,职责是简化程序员的业务逻辑实现。业务框架使程序员能够快速的开始编写游戏业务。
内置多种可选模块,可按需选择,以方便应用开发:
- 领域事件 (disruptor 实现类似Spring事件驱动模型 ApplicationEvent)
- 任务延时器 (将来某个时间可对任务进行执行、暂停、取消等操作,并不是类似 Quartz 的任务调度)
- 多环境切换 (不同运行环境下的配置支持)
- light-jprotobuf (补足 jprotobuf 不能让多个对象在单个 .proto 源文件中生成的需求,并简化jprotobuf对源文件的注释)
-
分步式锁 (基于Redisson的简单实现)
内置的其他功能:
- 心跳相关
- 用户上线、离线相关的钩子方法
- UserSessions (对所有用户UserSession的管理,统计在线用户等)
- UserSession (与 channel 是 1:1 的关系,可取到对应的 userId、channel 等信息。)
- 登录相关
集成相关:
- spring 集成 (业务框架可以方便的与 spring 进行集成,5 行代码)
后续计划:
- 抽象通用的游戏逻辑 (进一步减少开发实践过程中的工作量)
- 步骤表
- 帧同步
- 状态同步
业务交互简图
抽象的说,游戏前端与游戏服务端的的交互由上图组成。游戏前端与游戏服务端可以自由的双向交互,交互的业务数据由 .proto 作为载体。
协议文件
协议文件是对业务数据的描述载体,用于游戏前端与游戏服务端的数据交互。Protocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,也简称 PB。当然协议文件描述还可以是 json、xml或者任意自定义的,因为最后传输时会转换为二进制,但游戏开发中 PB 是目前的最佳。
游戏前端可以是 Unity、 UE(虚幻)、 Cocos或者其他的游戏引擎。
快速入门代码示例
Proto 协议文件定义
首先我们自定义一个协议文件,这个协议文件作为我们的业务载体描述。这个协议是纯java代码编写的,使用的是 jprotobuf, jprotobuf 是对 google protobuf 的简化使用,性能同等。
/** 请求 */
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class HelloReq {
String name;
}
Action
游戏服务端的编程,游戏服务端接收业务数据后,对业务数据进行处理;
@ActionController(1)
public class DemoAction {
@ActionMethod(0)
public HelloReq here(HelloReq helloReq) {
HelloReq newHelloReq = new HelloReq();
newHelloReq.name = helloReq.name + ", I'm here ";
return newHelloReq;
}
}
一个方法在业务框架中表示一个 Action(既一个业务动作)。
方法声名的参数是用于接收前端传入的业务数据,在方法 return 时,数据就可以被游戏前端接收到。程序员可以不需要关心业务框架的内部细节。
从上面的示例可以看出,这和普通的 java 类并无区别。如果只负责编写游戏业务,那么对于业务框架的学习可以到此为止了。
游戏编程就是如此简单!
访问示例(控制台
当我们访问 here 方法时(通常由游戏前端来请求),控制台将会打印
┏━━━━━ Debug. [(DemoAction.java:4).here] ━━━ [cmd:1 - subCmd:0 - cmdMerge:65536]
┣ userId : 888
┣ 参数: helloReq : HelloReq(name=塔姆)
┣ 响应: HelloReq(name=塔姆, I'm here )
┣ 时间: 0 ms (业务方法总耗时)
┗━━━━━ Debug [DemoAction.java] ━━━
快速从零编写服务器完整示例
如果觉得 ioGame 适合你,可以看一下 快速从零编写服务器完整示例 。在这个示例中,你可以用很少的代码实现一个完整的、可运行的、高性能的、稳定的服务器。
坦克游戏示例
ioGame 内提供了一个基于 FXGL 游戏引擎的游戏示例 (坦克射击启动文档),FXGL 是纯 java 开发的一个游戏引擎,可以在项目中直接运行。运行 TankApp.java 文件就可以启动游戏了。原计划用 U3D 来做游戏示例的,但想到大伙还得安装 u3d 的环境,就用 FXGL 来做游戏示例了。
适合人群?
- 长期从事 web 内部系统开发人员, 想了解游戏的
- 刚从事游戏开发的
- 未从事过游戏开发但却对其感兴趣的
- 对设计模式在实践中的应用和 sofa-bolt 有兴趣的学习者
推荐实际编程经验一年以上的人员