ioGame 是一个轻量级的网络编程框架,适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景。
源码完全开放、最新文档阅读完全开放,使用完全自由、免费(遵守开源协议)。
ioGame 具备一次编写到处对接的能力,为客户端提供了代码生成的辅助功能,能够帮助客户端开发者减少巨大的工作量。
你只需要编写一次 java 代码,就能为 Godot、UE、Unity、CocosCreator、Laya、React、Vue、Angular ...等项目生成统一的交互接口。 交互接口确保了方法的参数类型安全且明确,使我们在编译阶段就能发现潜在问题。 这种做法有效避免了安全隐患,并减少了联调时可能出现的低级错误。
支持语言: C#、TypeScript、GDScript、C++。
客户端请求服务器
Java Action
- C#
- TypeScript
- GDScript
- C++
public async Task TestLoginVerify()
{
var loginVerifyMessage = new LoginVerifyMessage { Jwt = "10" };
// code style: callback. Advantages: simple, integrated.
// cn: 编码风格:回调。 优点:简洁,一体化。
MyAction.OfLoginVerify(loginVerifyMessage, result =>
{
var userMessage = result.GetValue<UserMessage>();
result.Log(userMessage);
});
// code style: async await. Advantages: Avoid callback hell.
// cn: 编码风格:async await 机制。 优点:可避免回调地狱。
var result = await MyAction.OfAwaitLoginVerify(loginVerifyMessage);
var userMessage = result.GetValue<UserMessage>();
result.Log(userMessage);
}
public async Task TestIntValue()
{
const int value = 1;
MyAction.OfIntValue(value, result =>
{
result.Log(result.GetInt());
});
var result = await MyAction.OfAwaitIntValue(value);
result.Log(result.GetInt());
}
public async Task TestListString()
{
const string value = "hello";
MyAction.OfListString(value, result =>
{
result.Log(result.ListString());
});
var result = await MyAction.OfAwaitListString(value);
result.Log(result.ListString());
}
export async function testLoginVerify() {
const loginVerifyMessage = create(LoginVerifyMessageSchema, {jwt: "10"});
// code style: callback. Advantages: simple, integrated.
// cn: 编码风格:回调。 优点:简洁,一体化。
MyAction.ofLoginVerify(loginVerifyMessage, result => {
const message = result.getValue(UserMessageSchema);
result.log(message);
});
// code style: async await. Advantages: Avoid callback hell.
// cn: 编码风格:async await 机制。 优点:可避免回调地狱。
var result = await MyAction.OfAwaitLoginVerify(loginVerifyMessage);
const message = result.getValue(UserMessageSchema);
result.log(message);
}
export async function testIntValue() {
const value = 1;
MyAction.ofIntValue(value, result => {
result.log(result.getInt());
});
const result = await MyAction.ofAwaitIntValue(value);
result.log(result.getInt());
}
export async function testListString() {
const value = "hello";
MyAction.ofListString(value, result => {
result.log(result.listString());
});
const result = await MyAction.ofAwaitListString(value);
result.log(result.listString());
}
func test_login_verify():
var verify_message := Common.LoginVerifyMessage.new()
verify_message.set_jwt("10")
// code style: callback. Advantages: simple, integrated.
// cn: 编码风格:回调。 优点:简洁,一体化。
MyAction.of_login_verify(verify_message, func(result: IoGame.ResponseResult):
var user_message := result.get_value(Common.UserMessage) as Common.UserMessage
result.log(user_message)
)
// code style: async await. Advantages: Avoid callback hell.
// cn: 编码风格:async await 机制。 优点:可避免回调地狱。
var _result := await MyAction.of_await_login_verify(verify_message)
var user_message := result.get_value(Common.UserMessage) as Common.UserMessage
_result.log(user_message)
func test_int_value():
var value: int = 1
MyAction.of_int_value(value, func(result: IoGame.ResponseResult):
result.log(result.get_int())
)
var _result := await MyAction.of_await_int_value(value)
_result.log(_result.get_int())
func test_list_string():
var value := "hello"
MyAction.of_list_string(value, func(result: IoGame.ResponseResult):
result.log(result.list_string())
)
var _result := await MyAction.of_await_list_string(value)
_result.log(_result.list_string())
cn: 计划中
@ActionController(1)
public final class MyAction {
@ActionMethod(1)
public UserMessage loginVerify(LoginVerifyMessage verifyMessage) {
var userMessage = new UserMessage();
...
return userMessage;
}
@ActionMethod(2)
public int intValue(int value) {
return value + 1;
}
@ActionMethod(3)
public List<String> listString(String value) {
return List.of(value, "ioGame");
}
}
.proto
syntax = "proto3";
package common;
// LoginVerify
message LoginVerifyMessage {
// jwt
string jwt = 1;
}
// User
message UserMessage {
// userId
int64 user_id = 1;
// nickname
string name = 2;
}
客户端 SDK & 对接代码生成
ioGame 具备一次编写到处对接的能力,为客户端提供了代码生成的辅助功能,能够帮助客户端开发者减少巨大的工作量。
你只需要编写一次 java 代码,就能为 Godot、UE、Unity、CocosCreator、Laya、React、Vue、Angular ...等项目生成统一的交互接口。
支持语言: C#、TypeScript、GDScript、C++。
支持多种数据协议 & 连接方式
让开发者用一套业务代码,就能支持 Protobuf、JSON ...等数据协议,并支持扩展。
让开发者用一套业务代码,能同时支持多种连接方式,如 TCP、WebSocket、UDP ...等连接方式,并支持扩展。
自带负载均衡 & 支持集群、分布式
Broker (游戏网关)采用无中心节点、自动化的集群设计,所有节点平等且自治,不存在单点故障。
架构是可以动态扩缩的,游戏对外服、游戏逻辑服、Broker(游戏网关)都支持动态增加和减少。 无论未来玩家数量增加或减少,我们都能够轻松应对。
线程安全
框架为开发者解决了单个玩家的并发问题,即使玩家断线重连,也会使用相同的线程来消费业务。
框架在线程的扩展性上提供了友好的支持,开发者可以很容易的编写出无锁并发代码。
架构灵活性
架构由三部分组成:1.游戏对外服、2.Broker(游戏网关)、3.游戏逻辑服;三者既可相互独立,又可相互融合。
这意味着使用 ioGame 可以适应任何类型的游戏,因为只需通过调整部署方式,就可以满足不同类型的游戏需求。
功能模块化,游戏逻辑服组件化
游戏逻辑服是支持独立运行的,只需接入 Broker(游戏网关)上,就可以为玩家和其他游戏逻辑服提供功能上的扩展与增强。
我们可以将一些游戏逻辑服组件化,并制作成相对通用的组件,从而实现功能模块化的可能性。
支持多种通讯模型
与客户端通讯时,支持多种通讯模型。
broadcast : 服务器主动广播。
request/void: 单次请求处理时的,请求/无响应。
request/response: 单次请求处理时的,请求/响应。
类 MVC 的编码风格 & 避免类爆炸设计
为开发者提供了类 MVC 的编码风格(无入侵的 Java Bean ),这种设计方式很好的避免了类爆炸。
极好的编码体验 & 免写对接文档
代码即联调文档、JSR380验证、断言 + 异常机制 = 更少的维护成本
action 支持自动装箱、拆箱基础类型,用于解决协议碎片的问题 ...等诸多丰富的功能,使得开发者的业务代码更加的清晰、简洁。
模拟客户端请求
与单元测试不同的是,模拟客户端请求是模拟真实的网络环境,并且在模拟测试的过程中与服务器交互是可持续的、可互动的。
与前端同学联调某个功能时,不需要跟前端哥们说:“在点一下、在点一下、在点一下了”。这种“在点一下”的交流联调方式将成为过去式。
插件机制
业务框架提供了插件机制,插件是可插拨、可扩展的,框架内置提供了一些插件用于业务开发
合理利用好各个插件,可以让我们在开发阶段就能知道问题所在,提前发现问题,提前预防问题。