同步操作将从 渔民小镇/ioGame 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
过去、现在、将来都不会有商业版本,所有功能全部开源!
只做真的完全式开源,拒绝虚假开源,售卖商业版,不搞短暂维护!
承诺项目的维护周期是十年起步, 2022-03-01起,至少十年维护期!
提供高质量的使用文档!
如果您觉得还不错,帮忙给个 start 关注
.
开源地址: 基于 sofa-bolt 的网络游戏框架-源码地址
在线文档: 基于 sofa-bolt 的网络游戏框架-在线文档
推荐大家看在线文档,排版好一些,README 上看有点乱!
让网络游戏服务器的编程变得轻松简单!
ioGame 是国内首个基于蚂蚁金服 sofa-bolt 的网络游戏框架,游戏框架由 [网络通信框架] 和 [业务框架] 组成。
ioGame 是一个由 java 语言编写的网络游戏服务器框架。支持 websocket、tcp ,适用于全球同服、回合制游戏、策略游戏、即时战斗游戏,等游戏服务器的开发。具有高性能、稳定、易用易扩展、超好编程体验等特点。可做为 H5(HTML5)、手游、端游的游戏服务器。
在 ioGame 中能让你遗忘 Netty,你几乎没有机会能直接的接触到 Netty 的复杂,但却能享受 Netty 带来的高性能。对开发者要求低,为开发者节约开发时间。
通过 ioGame 可以快速的搭建一个稳定的、集群无中心节点、自带负载均衡、高性能的、分步式、避免类爆炸设计的网络游戏服务器。
游戏框架借助于蚂蚁金服 sofa-bolt 通信框架来提供稳定、高性能。
即使之前没有游戏编程的经验,也能参与到游戏编程中。如果你之前具备一些游戏开发或者 web MVC 相关的知识,则会更容易上手游戏服务器的开发。
源码内置了一个坦克射击游戏的示例,可直接运行。 坦克射击游戏是基于FXGL引擎(纯java的游戏引擎)开发的。 通过示例,可以快速的掌握网络游戏编程!
SOFABolt 是蚂蚁金融服务集团开发的一套基于 Netty 实现的网络通信框架。
Bolt 名字取自迪士尼动画-闪电狗,是一个基于 Netty 最佳实践的轻量、易用、高性能、易扩展的通信框架。
如果说 sofa-bolt 为了让 Java 程序员能将更多的精力放在基于网络通信的业务逻辑实现上。而业务框架正是解决业务逻辑如何方便的实现这一问题上。
业务框架是游戏框架的一部份,职责是简化程序员的业务逻辑实现,业务框架使程序员能够快速的开始编写游戏业务。
通过 ioGame 你可以很容易的搭建出一个集群、分步式的网络游戏服务器!
ioGame 可以很方便的与 spring 集成。支持多服多进程的方式部署,也支持多服单进程的方式部署。图中的每个对外服、每个游戏逻辑服、每个 broker (游戏网关)都可以在单独的进程或机器中部署,逻辑服之间可以跨进程通信(对外服也是逻辑服的一种)。这些进程可以在同一机器上,也可在不同的机器上。
游戏网关集群
broker (游戏网关)可以集群的方式部署,集群无中心节点、自带负载均衡。ioGame 本身就包含服务注册,你不需要外接一个服务注册中心,如 Eureka,ZooKeeper 等(变相的节约服务器成本)。
通过 broker (游戏网关) 的介入,之前非常复杂的负载均衡设计,如服务注册、健康度检查(后续版本提供)、到服务端的连接维护等这些问题,在 ioGame 中都不需要了,结构也简单了很多。
实际上单台 broker (游戏网关) 性能已经能够满足了,因为游戏网关只做了转发。
逻辑服
对外服和游戏逻辑服可以有很多个,逻辑服数量的理论上限是 netty 的连接上限。
抽象的说,游戏前端与游戏服务器的的交互由上图组成。游戏前端与游戏服务器可以自由的双向交互,交互的业务数据由 .proto 作为载体。
协议文件是对业务数据的描述载体,用于游戏前端与游戏服务的数据交互。Protocol Buffers (ProtocolBuffer/ protobuf ) 是Google公司开发的一种数据描述语言。也简称 PB。当然协议文件描述还可以是 json、xml或者任意自定义的,因为最后传输时会转换为二进制。但游戏开发中 PB 是目前的最佳。
游戏前端可以是 Unity、 UE(虚幻)、 Cocos或者其他的游戏引擎。游戏前端与用户的接触最为直接。
游戏服务器处理实际的用户等其他的业务数据。
这里主要介绍游戏服务器,毕竟是游戏服务器的框架。下面这个示例介绍了服务器编程可以变得如此简单。
首先我们自定义一个协议文件,这个协议文件作为我们的业务载体描述。这个协议是纯java代码编写的,使用的是 jprotobuf, jprotobuf 是对 google protobuf 的简化使用,性能同等。
可以把这理解成DTO、POJO、业务数据载体等,其主要目的是用于业务数据的传输;
/** 请求 */
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class HelloReq {
String name;
}
游戏服务器的编程,游戏服务器接收业务数据后,对业务数据进行处理;
@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] ━━━
Debug. [(DemoAction.java:4).here]: 表示执行业务的是 DemoAction 类下的 here 方法,4 表示业务方法所在的代码行数。在工具中点击控制台的 DemoAction.java:4 这条信息,就可以跳转到对应的代码中(快速导航到对应的代码)。
userId :
当前发起请求的 用户 id。参数 :
通常是游戏前端传入的值。响应 :
通常是业务方法返回的值 ,业务框架会把这个返回值推送到游戏前端。时间 :
执行业务方法总耗时,我们可根据业务方法总耗时的时长来优化业务。路由信息 :
路由是唯一的访问地址。
有了以上信息,游戏开发者可以很快的定位问题。
如果没有可视化的信息,开发中会浪费很多时间在前后端的沟通上。
问题包括:
是否传参问题 (游戏前端说传了)
是否响应问题(游戏后端说返回了)
业务执行时长问题 (游戏前端说没收到响应, 游戏后端说早就响应了)
其中代码导航可以让开发者快速的跳转到业务类对应代码中,在多人合作的项目中,可以快速的知道业务经过了哪些方法的执行,使得我们可以快速的进行阅读或修改;
推荐实际编程经验一年以上的人员
内置多种可选模块,可按需选择,以方便应用开发:
内置的其他功能:
集成相关:
已完成的示例:
示例代码在源码 example/ 目录下
后续计划:
当然每个框架都会给自身打上高性能,使用简单、易学易用、可扩展等各种有调调的标签。这里将从这么几个方面给出一些相关的解释,如:
性能方面
对接方面
通讯方式方面
开发方面
ioGame游戏框架由 [网络通信框架] 和 [业务框架] 组成。所以我们只需要关注使用最频繁的两个点:1. 网络传输的性能,2.调用开发者编写的业务代码(action)。
1. 网络传输的性能
网络传输方面的性能上限取决于网络通信框架 sofa-bolt。
2.调用开发者编写的业务代码(action)
业务框架对于每个 action (既业务的处理类) 都是通过 asm、Singleton、Flyweight 、Command 等结合,对 action 的获取上通过 array 来得到,是一种近原生的方式。
日常中,我们编写完成业务需求后,就会与游戏前端的同学进行联调对接的环节。在对接前需要提供相应的对接文档,如:如何访问该需求的业务方法、访问该业务方法需要什么参数、会得的响应是什么、对于该业务方法的描述等等。
对于这方面 ioGame 也提供了一些辅助 游戏文档生成,通过该辅助可以做到代码既文档,就是说当你的业务编写完成后,不需要额外的编写业务对接文档了,框架会自动的生成最新的文档。
如果没有游戏文档生成,那么你将要抽出一些时间来维护文档的工作,而且当团队人数多了,就会很乱(文档不同步、不是最新的、或是忘记更新等等情况就会出现)。
框架提供了 3 类通讯方式:单次请求处理、推送、逻辑服间的相互通信。发挥你的想象力,把这 3 类通讯方式用活,可以满足很多业务。
1.单次请求处理
a. 请求、无响应、b. 请求、响应
2.推送
a. 指定单个或多个用户广播(推送)、b. 全服广播(推送)
3.逻辑服间的相互通信
a. 单个逻辑服与单个逻辑服通信请求(可跨进程)、b. 单个逻辑服与同类型多个逻辑服通信请求(可跨进程)(后续版本提供)
ioGame 非常注重开发者的开发体验,学习零成本。在开发方面又包括这几个小方面:开发体验方面、参数方面、参数的数据验证方面、异常机制方面、调试方面。
1.零学习成本,一个普通的 java 方法就是一个 action。
2.方法参数就是请求端给的请求参数。
3.方法返回值(响应结果)会给到请求端。
可以看到,框架屏蔽了通信细节,从而使得开发变得很简单,可以说是学习零成本(因为这是一个普通的 java 方法),同时这种设计方式避免了类爆炸。
参考:快速入门样例
@ActionController(1)
public class DemoAction {
@ActionMethod(1)
public HelloReq jackson(HelloReq helloReq) throws MsgException {
String jacksonName = "jackson";
if (jacksonName.equals(helloReq.name) == false) {
throw new MsgException(101, "名字不正确!");
}
helloReq.name = helloReq.name + ", hello, jackson !";
return helloReq;
}
}
action 有这么几个组成部分:方法名、方法参数、方法体、方法返回值、方法的异常、方法的调用。业务框架关注有这么几个点:1.方法的调用、2.方法参数的验证、3.方法的异常处理机制、4.方法的返回值。
框架对 jprotobuf通信协议的友好支持,通信协议这里指游戏端与游戏服务端之间的业务数据传递。例如:登录业务的登录请求(游戏端请求游戏服务端)与登录响应(游戏服务端返回数据给游戏端)。jprotobuf 是对 google protobuf 的简化使用,性能同等。
框架支持 JSR303+ 相关验证规范,业务参数的验证不在需要写在业务代码里面,可以使得业务代码更干净。若不使用验证框架,常规的做法是不断的在业务代码中疯狂使用 if else 输出,使得业务代码混乱。
业务框架支持异常机制,有了异常机制可以使得业务代码更加的清晰。也正是有了异常机制,才能做到零学习成本(普通的 java 方法成为一个业务动作 action )。
如果有业务上的异常,请直接抛出去,不需要开发者做过多的处理,业务框架会知道如何处理这个业务异常,这些抛出去的业务异常总是能给到游戏的请求端的。
参考:异常机制
在项目开发阶段,框架提供了对于请求访问的一些日志打印和业务代码定位--神级特性 (可以让你知道哪些业务方法被调用了,并能快速的跳转到对应的业务代码中)。
其中代码导航可以让开发者快速的跳转到业务类对应代码中,在多人合作的项目中,可以快速的知道业务经过了哪些方法的执行,使得我们可以快速的进行阅读或修改;
对于这块更详细的说明在业务日志中有介绍
业务框架的关注点:
开发方面:1.开发体验、2.参数 、3.参数的数据验证方面(方法参数的验证)、4.异常机制、5.调试日志(业务日志)
对接方面:1.游戏文档生成
这几个方面是我们开发中最常用的,也是用得最为频繁的。如果满足不了上面最为基础的几个方面,谈不上是一个好用的框架。
.
├── common
│ ├── common-core (业务框架)
│ └── common-kit (工具相关)
├── example (示例)
│ ├── example-broadcast (广播示例)
│ ├── example-cluster-run-one (集群示例)
│ ├── example-endpoint 示例目录 玩家动态绑定逻辑服节点
│ ├── example-for-spring (spring集成示例)
│ ├── example-for-tcp-socket (对外服使用tcp协议示例)
│ ├── example-hook 示例目录 钩子相关(心跳,用户上线、下线)
│ ├── example-interaction (逻辑服与逻辑服之间的交互,可跨进程通信)
│ ├── example-interaction-same 示例目录 逻辑服间的相互通信;请求同类型多个逻辑服的结果集(可跨进程)
│ ├── example-parent
│ ├── example-redisson-lock (分步式锁)
│ ├── example-redisson-lock-spring-boot-starter (分步式锁 for springBootStarter)
│ └── example-run-one (快速启动示例)
├── example-game-collect (实战示例、坦克)
│ ├── fxgl-tank (游戏引擎-坦克游戏启动端)
│ ├── game-common (一些通用的功能)
│ ├── game-common-proto (示例 pb )
│ ├── game-external (对外服)
│ ├── game-logic-hall (登录逻辑服)
│ ├── game-logic-tank (坦克逻辑服)
│ └── game-one (一键启动 游戏网关、游戏逻辑服(登录和坦克)、对外服)
├── net-bolt (网络通信框架相关的:对外服、游戏网关、游戏逻辑服)
│ ├── bolt-broker-server (游戏网关)
│ ├── bolt-client (逻辑服)
│ ├── bolt-core (游戏网关和逻辑服 ,bolt 相关 core 包)
│ ├── bolt-external (对外服, 也是逻辑服的一种)
│ └── bolt-run-one (单体启动辅助,一个进程内可以启动 : 对外服、游戏网关、游戏逻辑服)
└── widget (内置多种可选模块)
├── light-domain-event (领域事件)
├── light-jprotobuf (生成 .proto 源文件)
├── light-profile (多环境切换)
├── light-redis-lock (分步式锁 ,基于Redisson的简单实现)
├── light-redis-lock-spring-boot-starter (分步式锁 ,基于Redisson的简单实现)
└── light-timer-task (任务延时器)
如果觉得 ioGame 适合你,可以看一下 快速从零编写服务器完整示例 。在这个示例中,你可以用很少的代码 实现一个完整的、可运行的、高性能的、稳定的服务器。
ioGame 内提供了一个基于 FXGL 游戏引擎的游戏示例(坦克射击启动文档),FXGL 是纯 java 开发的一个游戏引擎,可以在项目中直接运行。
运行 TankApp.java 文件就可以启动游戏了。
原计划用 U3D 来做游戏示例的,但想到大伙还得安装 u3d 的环境,就用 FXGL 来做游戏示例了。
如果您觉得还不错,帮忙给个 start 关注
什么是 Action。
坦克示例(坦克游戏前端)。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。