Releases: iohao/ioGame
ioGame 21.19 netty 分布式网络游戏服务器框架,真轻量级网络编程框架
Documentation and Logs
Releases: 1 to 2 versions are released every month, and upgrades within a major version are always compatible, such as 21.1 is upgraded to any higher version 21.x
Version update summary
- [core] FlowContext provides the setUserId method to simplify the login operation.
- [broker] Added RingElementSelector load balancing implementation and set it as default to replace RandomElementSelector
- [core] #386 Action supports constructor injection with parameters in Spring
- Simplify the implementation class of ActionParserListener related to ProtoDataCodec. and #386
- perf(i18n): 🐳 #376 cmd check tips
- refactor(external): simplify and improve externalCache
[core] FlowContext provides the setUserId method to simplify the login operation.
@ActionController(LoginCmd.cmd)
public class TheLoginAction {
... ...
@ActionMethod(LoginCmd.login)
public UserInfo loginVerify(LoginVerify loginVerify, FlowContext flowContext) {
long userId = ...;
// Deprecated
boolean success = UserIdSettingKit.settingUserId(flowContext, userId);
// now
boolean success = flowContext.setUserId(userId);
return ...;
}
}
[core] #386 Action supports constructor injection with parameters in Spring
// Action supports constructor injection in Spring.
@Component
@AllArgsConstructor
@ActionController(PersonCmd.cmd)
public class PersonAction {
final PersonService personService;
...
}
refactor(external): simplify and improve externalCache
// create externalCache
private static void extractedExternalCache() {
// Deprecated
DefaultExternalCmdCache externalCmdCache = new DefaultExternalCmdCache();
// now
var externalCmdCache = ExternalCmdCache.of();
}
[other updates]
<netty.version>4.1.114.Final</netty.version>
ioGame 21.18 netty 分布式网络游戏服务器框架,真轻量级网络编程框架
文档与日志
- ioGame javadoc api
- 框架版本更新日志 (yuque.com) - ioGame update logs
- ioGame 真.轻量级网络编程框架 - 在线使用文档 - User Manual
ioGame 每月会发 1 ~ 2 个版本,通常在大版本内升级总是兼容的,如 21.1 升级到任意 21.x 的高版本。
Releases: 1 to 2 versions are released every month, and upgrades within a major version are always compatible, such as 21.1 is upgraded to any higher version 21.x
版本更新汇总
[core]
#376 Support i18n, such as logs and internal messages. 框架内的日志、内部消息支持 i18n。
public class DemoApplication {
public static void main(String[] args) {
// setting defaultLocale, such as US or CHINA
Locale.setDefault(Locale.US);
Locale.setDefault(Locale.CHINA);
... start ioGame
}
}
[其他更新]
<scalecube.version>2.6.17</scalecube.version>
ioGame 21.17 netty 分布式网络游戏服务器框架,真轻量级网络编程框架
文档与日志
ioGame 每月会发 1 ~ 2 个版本,通常在大版本内升级总是兼容的,如 21.1 升级到任意 21.x 的高版本。
版本更新汇总
- [core] 简化 TraceIdSupplier 默认实现(全链路调用日志跟踪)
- [core] FlowContext 提供用户(玩家)所关联的用户线程执行器信息及虚拟线程执行器信息方法
[core]
FlowContext 提供用户(玩家)所关联的用户线程执行器信息及虚拟线程执行器信息方法
void testThreadExecutor(FlowContext flowContext) {
// 获取 - 用户(玩家)所关联的用户线程执行器信息及虚拟线程执行器信息
// 用户虚拟线程执行器信息
ThreadExecutor virtualThreadExecutor = flowContext.getVirtualThreadExecutor();
// 用户线程执行器信息
ThreadExecutor threadExecutor = flowContext.getThreadExecutor();
threadExecutor.execute(() -> {
log.info("execute");
});
threadExecutor.executeTry(() -> {
log.info("executeTry");
});
// get Executor
Executor executor = threadExecutor.executor();
}
netty 分布式网络游戏服务器框架,真轻量级网络编程框架 ioGame 21.16
文档与日志
ioGame 每月会发 1 ~ 2 个版本,通常在大版本内升级总是兼容的,如 21.1 升级到任意 21.x 的高版本。
版本更新汇总
- [kit] #291 增加轻量可控的延时任务
- [kit] 细分时间日期相关工具。
- [Archive] #363 light-redis-lock 相关模块
- [Archive] #364 light-timer-task 相关模块
- [core] 增加同一个 ActionController 相同的 action 方法名只允许存在一个的检测。
- [core] Banner 增加启动时的错误数量提示。
- [core] #365 支持对接文档生成时,可以根据路由访问权限来控制文档的生成
[kit]
#291 增加轻量可控的延时任务
for example
@Test
public void example() {
long timeMillis = System.currentTimeMillis();
DelayTask delayTask = DelayTaskKit.of(() -> {
long value = System.currentTimeMillis() - timeMillis;
log.info("1 - 最终 {} ms 后,执行延时任务", value);
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
delayTask.plusTimeMillis(500); // 增加 0.5 秒的延时
delayTask.minusTimeMillis(500);// 减少 0.5 秒的延时时间
// 因为 taskId 相同,所以会覆盖之前的延时任务
String taskId = delayTask.getTaskId();
delayTask = DelayTaskKit.of(taskId, () -> {
long value = System.currentTimeMillis() - timeMillis;
log.info("2 - 最终 {} ms 后,执行延时任务", value);
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
// 取消延时任务,下面两个方法是等价的
delayTask.cancel();
DelayTaskKit.cancel(taskId);
// 可以通过 taskId 查找该延时任务
Optional<DelayTask> optionalDelayTask = DelayTaskKit.optional(taskId);
if (optionalDelayTask.isPresent()) {
var delayTask = optionalDelayTask.get();
}
// 通过 taskId 查找延时任务,存在则执行给定逻辑
DelayTaskKit.ifPresent(taskId, delayTask -> {
delayTask.plusTimeMillis(500); // 增加 0.5 秒的延时时间
});
}
细分时间日期相关工具。
see com.iohao.game.common.kit.time
[Archive]
#363 light-redis-lock 相关模块
将 light-redis-lock、light-redis-lock-spring-boot-starter 模块做归档。
在过去的时间里,由于一直没有改动这些模块的相关内容,现决定将不再上传到 maven 库中,以节约公共资源。如果你使用了该模块的相关内容,请指定最后一个版本即可。如
<!-- https://mvnrepository.com/artifact/com.iohao.game/light-redis-lock -->
<dependency>
<groupId>com.iohao.game</groupId>
<artifactId>light-redis-lock</artifactId>
<version>21.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.iohao.game/light-redis-lock-spring-boot-starter -->
<dependency>
<groupId>com.iohao.game</groupId>
<artifactId>light-redis-lock-spring-boot-starter</artifactId>
<version>21.15</version>
</dependency>
模块相关文档 - redis-lock 分布式锁 (yuque.com)
#364 light-timer-task 相关模块
将 light-timer-task 模块做归档。
在过去的时间里,由于一直没有改动这些模块的相关内容;同时,也因为框架内置了类似的功能 #291 。现决定将不再上传到 maven 库中,以节约公共资源。如果你使用了该模块的相关内容,请指定最后一个版本即可。如
<!-- https://mvnrepository.com/artifact/com.iohao.game/light-timer-task -->
<dependency>
<groupId>com.iohao.game</groupId>
<artifactId>light-timer-task</artifactId>
<version>21.15</version>
</dependency>
模块相关文档 - timer-task 任务延时器 (yuque.com)
类似的代替 轻量可控的延时任务 (yuque.com)
[core]
#365 支持对接文档生成时,可以根据路由访问权限来控制文档的生成
生成相关代码的使用及相关文档
ExternalGlobalConfig.accessAuthenticationHook
,相关文档 - 路由访问权限控制 (yuque.com)- IoGameDocumentHelper,相关文档 - 游戏对接文档生成 (yuque.com)
for example
public class MyExternalServer {
public static void extractedAccess() {
// https://www.yuque.com/iohao/game/nap5y8p5fevhv99y
var accessAuthenticationHook = ExternalGlobalConfig.accessAuthenticationHook;
... 省略部分代码
// 添加 - 拒绝玩家访问权限的控制
accessAuthenticationHook.addRejectionCmd(RankCmd.cmd, RankCmd.internalUpdate);
}
}
public class TestGenerate {
... 省略部分代码
public static void main(String[] args) {
// 对外服访问权限控制
MyExternalServer.extractedAccess();
// (复用)设置文档路由访问权限控制
IoGameDocumentHelper.setDocumentAccessAuthentication(ExternalGlobalConfig.accessAuthenticationHook::reject);
// ====== 生成对接文档、生成 proto ======
// generateCsharp();
// generateTypeScript();
// 生成文档
IoGameDocumentHelper.generateDocument();
// .proto 文件生成
// generateProtoFile();
}
}
预览 - 没有做控制前的生成
==================== RankAction ====================
路由: 4 - 1 --- 【listRank】 --- 【RankAction:48】【listRank】
方法参数: StringValue 排行类型
方法返回值: ByteValueList<RankUpdate> 玩家排行名次更新
路由: 4 - 10 --- 【玩家排行名次更新】 --- 【RankAction:60】【internalUpdate】
方法参数: RankUpdate 玩家排行名次更新
方法返回值: void
预览 - 加入了访问控制后的生成
我们可以看见,路由为 4-10 的 action 方法没有生成到对接文档中。
==================== RankAction ====================
路由: 4 - 1 --- 【listRank】 --- 【RankAction:48】【listRank】
方法参数: StringValue 排行类型
方法返回值: ByteValueList<RankUpdate> 玩家排行名次更新
提示:除了文档文档的访问权限控制外,还支持 SDK TypeScript、SDK C# ...等客户端代码生成的访问权限控制。
SDK 相关请阅读:SDK&对接文档 (yuque.com)
[其他更新]
<netty.version>4.1.113.Final</netty.version>
netty 分布式网络游戏服务器框架 & 真轻量级网络编程框架 ioGame 21.15
文档与日志
通常在大版本内升级总是兼容的,如 21.1 升级到任意 21.x 的高版本。
ioGame 发版本的频率:每月会发 1 ~ 2 个版本。
版本更新汇总
- [core] #351 增加 UserProcessor 线程执行器的选择策略扩展
- [core] #350 修复请求消息在 Broker 环节乱序的问题
- [core] #353 对接文档支持框架内置错误码的生成
- [core] #354 日志打印调整
- [core] #359 [逻辑服-监听] 增加打印其他进程逻辑服的上线与下线信息
- [core] 优化 ThreadExecutorRegion 相关实现类。
- [external] UserSession 接口新增 ofRequestMessage 方法,简化玩家在游戏对外服中创建请求对象。
[external]
UserSession 接口新增 ofRequestMessage 方法,简化玩家在游戏对外服中创建请求对象。
for example
var cmdInfo = CmdInfo.of(1, 1);
RequestMessage request = userSession.ofRequestMessage(cmdInfo);
[core]
#359 [逻辑服-监听] 增加打印其他进程逻辑服的上线与下线信息
public class MyLogicServer extends AbstractBrokerClientStartup {
...
@Override
public BrokerClientBuilder createBrokerClientBuilder() {
BrokerClientBuilder builder = BrokerClient.newBuilder();
...
// 添加监听 - 打印其他进程逻辑服的上线与下线信息
builder.addListener(SimplePrintBrokerClientListener.me());
return builder;
}
}
#351 增加 UserProcessor 线程执行器的选择策略扩展
for example
// 为请求消息开启有序的、多线程处理的优化
IoGameGlobalConfig.enableUserProcessorExecutorSelector();
注意事项:当你的 UserProcessor 做了线程执行器的选择策略扩展,需要重写 CustomSerializer 接口的相关方法。
ioGame 21.14,netty 分布式游戏服务器框架;java 分步式游戏服务器框架;
ioGame 发版本的频率:每月会发 1 ~ 2 个版本。通常在大版本内升级总是兼容的,如 21.1 升级到任意 21.x 的高版本。
文档与日志
版本更新汇总
- [code quality] 提升代码质量
- [javadoc] 增强相关模块的 javadoc :业务框架、压测与模拟客户端请求、领域事件、Room
- [core] #346 业务框架 InOutManager 提供扩展点
- [core] #344 登录时,如果 FlowContext 存在 userId 就不请求游戏对外服
- [broker] fixed #342 非集群环境下,Broker 断开重启后,逻辑服没有将其重新加入到 BrokerClientManager 中所引发的 NPE。
[core]
#346 业务框架 InOutManager 提供扩展点
在构建器中配置 InOutManager 策略,框架内置了两个实现类,分别是
- ofAbcAbc :in ABC,out ABC 的顺序,即编排时的顺序。
- ofPipeline:in ABC,out CBA 的顺序,类似的 netty Pipeline 。(默认策略,如果不做任何设置,将使用该策略)
for example
在构建器中配置 InOutManager 策略
public void config() {
BarSkeletonBuilder builder = ...;
builder.setInOutManager(InOutManager.ofAbcAbc());
builder.setInOutManager(InOutManager.ofPipeline());
}
ioGame 21.13,netty 分布式游戏服务器框架;java 分步式游戏服务器框架;
文档与日志
版本更新汇总
- [external] #334 顶号操作 bug,有概率触发并发问题
- [core] FlowContext 新增 createRequestCollectExternalMessage 方法
- [javadoc] 源码 javadoc 增强
[core]
FlowContext 新增 createRequestCollectExternalMessage 方法,request 与游戏对外服交互。相关使用文档请阅读 获取游戏对外服的数据与扩展 (yuque.com)
... ... 省略部分代码
@ActionMethod(ExternalBizRegionCmd.listOnlineUserAll)
public List<Long> listOnlineUserAll(FlowContext flowContext) {
// 创建 RequestCollectExternalMessage
var request = flowContext
.createRequestCollectExternalMessage(MyExternalBizCode.onlineUser);
// 访问多个【游戏对外服】
var collectExternalMessage = flowContext
.invokeExternalModuleCollectMessage(request);
return listUserId(collectExternalMessage);
}
[其他更新]
<netty.version>4.1.112.Final</netty.version>
<lombok.version>1.18.34</lombok.version>
ioGame 21.12,netty 分布式游戏服务器框架;java 分步式游戏服务器框架;
文档与日志
版本更新汇总
- [light-game-room] #326 GameFlowContext getRoom、getPlayer 方法返回值改成泛型
- [对接文档] #330 增强,支持对接文档生成与扩展,包括文本文档生成、联调代码生成 ...等
[light-game-room]
#326 GameFlowContext getRoom、getPlayer 方法返回值改成泛型
GameFlowContext gameFlowContext = ...;
// FightRoomEntity、FightPlayerEntity 是自定义的 Room、Player 对象
// Room、Player 在使用时,不需要强制转换了
FightRoomEntity room = gameFlowContext.getRoom();
FightPlayerEntity player = gameFlowContext.getPlayer();
[对接文档]
#330 增强,支持对接文档生成与扩展,包括文本文档生成、联调代码生成 ...等。开发者做更多个性化的扩展
在该版本中,我们已经新做了对接文档相关模块;该版本功能更加的强大,使用上也更加的简洁。新版本的对接文档模块,除了能提供文本文档的生成外,还能支持生成与客户端联调的代码、并且是可扩展的。通常,客户端联调代码有:
- 支持生成 C# 客户端的联调代码,通常用在 Unity、Godot 客户端,具体可阅读 SDK C# 代码生成。
- 支持生成 TypeScript 客户端的联调代码,通常用在 cocos、laya 客户端,具体可阅读 SDK TypeScript 代码生成。
public static void main(String[] args) {
// 添加枚举错误码 class,用于生成错误码相关信息
IoGameDocumentHelper.addErrorCodeClass(GameCode.class);
// 添加文档生成器,文本文档
IoGameDocumentHelper.addDocumentGenerate(new TextDocumentGenerate());
// 添加文档生成器,Ts 联调代码生成
IoGameDocumentHelper.addDocumentGenerate(new TypeScriptDocumentGenerate());
// 生成文档
IoGameDocumentHelper.generateDocument();
}
上述代码
- 添加了错误码的生成
- 添加了文本文档的生成
- 添加了 Ts 客户端联调代码的生成(包括 action、广播、错误码...相关代码的生成), SDK TypeScript 客户端代码生成;方便 CocosCeator、或其他支持 TypeScript 的客户端对接。 #329
addDocumentGenerate 是可扩展的,这将意味着开发者可以扩展出 C#、GodotScript、Js ...等不同客户端的联调代码。默认,我们提供了一个文本文档,即 TextDocumentGenerate,如果默认的实现满足不了当下需求,开发者也可以定制个性化的文档,如 json 格式的。
更多内容请阅读 游戏对接文档生成 (yuque.com)
新增 DocumentGenerate 接口
开发者可利用该接口进行定制个性化的对接文档,如代码生成 ...等。
/**
* 对接文档生成接口,可扩展不同的实现
*/
public interface DocumentGenerate {
/**
* 生成文档
*
* @param ioGameDocument ioGameDocument
*/
void generate(IoGameDocument ioGameDocument);
}
/**
* 文档相关信息,如 action 相关、广播相关、错误码相关。
*/
@Getter
public final class IoGameDocument {
/** 已经解析好的广播文档 */
List<BroadcastDocument> broadcastDocumentList;
/** 已经解析好的错误码文档 */
List<ErrorCodeDocument> errorCodeDocumentList;
/** 已经解析好的 action 文档 */
List<ActionDoc> actionDocList;
}
开发者可以通过实现 DocumentGenerate 接口来扩展不同的文档生成,开发者可以扩展此接口来定制更多个性化的扩展,如
- html 版本的文档。
- json 版本的文档。
- 其他语言的联调文档 ...等。
// 使用示例
private static void test() {
var documentGenerate = new YourDocumentGenerate();
IoGameDocumentHelper.addDocumentGenerate(documentGenerate);
}
其他:废弃旧版本对接文档相关类 DocActionSend、DocActionSends、ActionDocs、ActionSendDoc、ActionSendDocs、ActionSendDocsRegion、BarSkeletonDoc、BroadcastDoc、BroadcastDocBuilder、ErrorCodeDocs、ErrorCodeDocsRegion。
21.10 及之前版本的使用示例(对接文档)
public static void main(String[] args) {
... 省略部分代码
new NettyRunOne()
... ...
.startup();
// 生成对接文档
BarSkeletonDoc.me().buildDoc();
}
ioGame 21.10,netty 分布式游戏服务器框架;java 分步式游戏服务器框架;
文档与日志
版本更新汇总
- [core] #315 ResponseMessage 增加协议碎片便捷获取,简化跨服调用时的使用
- [core] ActionCommand 增加 containAnnotation、getAnnotation 方法,简化获取 action 相关注解信息的使用。
- [kit] [动态属性] 增加 ifNull 方法,如果动态属性值为 null,则执行给定的操作,否则不执行任何操作。执行给定操作后将得到一个返回值,该返回值会设置到动态属性中。
- [kit] TimeKit 增加 nowLocalDate 方法,可减少 LocalDate 对象的创建;优化 currentTimeMillis 方法的时间更新策略。同时,优化 nowLocalDate、currentTimeMillis 方法,不使用时将不会占用相关资源。
- [EventBus] 分布式事件总线增加 EventBusRunner 接口。EventBus 接口化,方便开发者自定义扩展。fix 订阅者使用自身所关联的 EventBus 处理相关事件。
[core] 315 ResponseMessage 增加协议碎片便捷获取,简化跨服调用时的使用
框架具备协议碎片特性。某些业务中,我们需要跨服访问其他游戏逻辑服,以获取某些业务数据;一些简单的数据,我们可以通过协议碎片来返回,从而避免定义过多的协议。
现为 ResponseMessage 增加协议碎片支持,简化跨服调用时的使用,新增的方法如下
public void test() {
ResponseMessage responseMessage = ...;
// object
responseMessage.getValue(Student.class);
List<Student> listValue = responseMessage.listValue(Student.class);
// int
int intValue = responseMessage.getInt();
List<Integer> listInt = responseMessage.listInt();
// long
long longValue = responseMessage.getLong();
List<Long> listLong = responseMessage.listLong();
// String
String stringValue = responseMessage.getString();
List<String> listString = responseMessage.listString();
// boolean
boolean boolValue = responseMessage.getBoolean();
List<Boolean> listBoolean = responseMessage.listBoolean();
}
示例说明
- HomeAction 是 【Home 游戏逻辑服】提供的 action
- UserAction 是 【User 游戏逻辑服】提供的 action
两个逻辑服的交互如下,UserAction 使用跨服方式调用了【Home 游戏逻辑服】的几个方法,并通过 responseMessage 的协议碎片支持,简化跨服调用时的使用。
示例中演示了 string、string list、object list 的简化使用(协议碎片获取时的简化使用)。
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Student {
String name;
}
// home 游戏逻辑服提供的 action
public class HomeAction {
@ActionMethod(HomeCmd.name)
public String name() {
return "a";
}
@ActionMethod(HomeCmd.listName)
public List<String> listName() {
return List.of("a", "b");
}
@ActionMethod(HomeCmd.listStudent)
public List<Student> listStudent() {
Student student = new Student();
student.name = "a";
Student student2 = new Student();
student2.name = "b";
return List.of(student, student2);
}
}
@ActionController(UserCmd.cmd)
public class UserAction {
@ActionMethod(UserCmd.userSleep)
public void userSleep(FlowContext flowContext) {
flowContext.invokeModuleMessageAsync(HomeCmd.of(HomeCmd.name), responseMessage -> {
String name = responseMessage.getString();
log.info("{}", name);
});
flowContext.invokeModuleMessageAsync(HomeCmd.of(HomeCmd.listName), responseMessage -> {
var listName = responseMessage.listString();
log.info("{}", listName);
});
flowContext.invokeModuleMessageAsync(HomeCmd.of(HomeCmd.listStudent), responseMessage -> {
List<Student> studentList = responseMessage.listValue(Student.class);
log.info("{}", studentList);
});
}
}
[core] ActionCommand 增加 containAnnotation、getAnnotation 方法,简化获取 action 相关注解信息的使用。
ActionCommand actionCommand = flowContext.getActionCommand();
bool contain = actionCommand.containAnnotation(DisableDebugInout.class);
var annotation = actionCommand.getAnnotation(DisableDebugInout.class);
[EventBus] 分布式事件总线
- [增强扩展] 将抽象类 AbstractEventBusRunner 标记为过时的,由接口 EventBusRunner 代替。
- [增强扩展] 分布式事件总线 EventBus 接口化,方便开发者自定义扩展。增加总线相关的 javadoc。
- [fix] 订阅者使用自身所关联的 EventBus 处理相关事件。
关于 fix 订阅者使用自身所关联的 EventBus 处理相关事件,在此之前可能引发 bug 的场景如下
- 【游戏逻辑服 A】 发布事件。
- 【游戏逻辑服 B】 订阅者接收事件并处理,在处理过程中又调用了【游戏逻辑服 A】 某个 action 方法。
该业务场景,会在多服单进程下会引发调用超时,但在多服多进程下则不会超时。
[kit] TimeKit
增强 TimeKit 增加 nowLocalDate 方法,可减少 LocalDate 对象的创建;
优化 currentTimeMillis 方法的时间更新策略。
优化 nowLocalDate、currentTimeMillis 不使用时将不会占用相关资源。
@Test
public void test() {
long millis = TimeKit.currentTimeMillis();
Assert.assertTrue(millis > 0);
LocalDate localDate = TimeKit.nowLocalDate();
Assert.assertTrue(localDate.isEqual(LocalDate.now()));
}
[kit] 动态属性
[动态属性] 增加 ifNull 方法,如果动态属性值为 null,则执行给定的操作,否则不执行任何操作。执行给定操作后将得到一个返回值,该返回值会设置到动态属性中。
public class AttrOptionDynamicTest {
// 动态属性 key
AttrOption<AttrCat> attrCatOption = AttrOption.valueOf("AttrCat");
@Test
public void ifNull() {
var myAttrOptions = new MyAttrOptions();
Assert.assertNull(myAttrOptions.option(attrCatOption));
// 如果 catAttrOption 属性为 null,则创建 AttrCat 对象,并赋值到属性中
myAttrOptions.ifNull(attrCatOption, AttrCat::new);
Assert.assertNotNull(myAttrOptions.option(attrCatOption));
}
private static class AttrCat {
String name;
}
@Getter
private static class MyAttrOptions implements AttrOptionDynamic {
final AttrOptions options = new AttrOptions();
}
}
[其他 - 相关库升级]
<netty.version>4.1.111.Final</netty.version>
<jctools-core.version>4.0.5</jctools-core.version>
<jprotobuf.version>2.4.23</jprotobuf.version>
ioGame 21.9,java 高性能游戏服务器框架;netty 高性能游戏服务器框架
21.9
文档与日志
版本更新汇总
- [core] #294 增加范围内的广播接口 RangeBroadcaster,业务参数支持基础类型(协议碎片)的简化使用
- [core-对接文档] #293 广播文档构建器支持对参数的单独描述
- [light-game-room] #297 模拟系统创建房间,RoomCreateContext 的使用
- [light-game-room] #298 模拟系统创建房间,GameFlowContext 的使用
- [core] #301 FlowContext 更新元信息后,需要立即生效(跨服调用时)
- [内置 kit] 开放 TaskListener 接口
- 为 SimpleRoom aggregationContext 属性提供默认值,移除 RoomCreateContext 接口的 getAggregationContext 方法,以免产生误导。
[light-game-room]
为 SimpleRoom aggregationContext 属性提供默认值
#297,模拟系统创建房间,RoomCreateContext 的使用
移除 RoomCreateContext 接口的 getAggregationContext 方法,以免产生误导。
RoomCreateContext 增加默认重载
RoomCreateContext.of(); // 无房间创建者,通常表示系统创建
RoomCreateContext.of(userId); // 房间创建者为 userId
#298 模拟系统创建房间,GameFlowContext 的使用
public void test() {
Room room = ...;
GameFlowContext context = GameFlowContext.of(room);
... 省略部分代码
}
[core]
#294 增加范围内的广播接口 RangeBroadcaster,业务参数支持基础类型(协议碎片)的简化使用
public void testRangeBroadcaster(FlowContext flowContext) {
// ------------ object ------------
// 广播 object
DemoBroadcastMessage message = new DemoBroadcastMessage();
message.msg = "helloBroadcast --- 1";
RangeBroadcaster.of(flowContext)
.setResponseMessage(cmdInfo, message);
// 广播 object list
List<DemoBroadcastMessage> messageList = List.of(message);
RangeBroadcaster.of(flowContext)
.setResponseMessageList(cmdInfo, messageList);
// ------------ int ------------
// 广播 int
int intValue = 1;
RangeBroadcaster.of(flowContext)
.setResponseMessage(cmdInfo, intValue);
// 广播 int list
List<Integer> intValueList = List.of(1, 2);
RangeBroadcaster.of(flowContext)
.setResponseMessageIntList(cmdInfo, intValueList);
// ------------ long ------------
// 广播 long
long longValue = 1L;
RangeBroadcaster.of(flowContext)
.setResponseMessage(cmdInfo, longValue);
// 广播 long list
List<Long> longValueList = List.of(1L, 2L);
RangeBroadcaster.of(flowContext)
.setResponseMessageLongList(cmdInfo, longValueList);
// ------------ String ------------
// 广播 String
String stringValue = "1";
RangeBroadcaster.of(flowContext)
.setResponseMessage(cmdInfo, stringValue);
// 广播 String list
List<String> stringValueList = List.of("1L", "2L");
RangeBroadcaster.of(flowContext)
.setResponseMessageStringList(cmdInfo, stringValueList);
// ------------ boolean ------------
// 广播 boolean
boolean boolValue = true;
RangeBroadcaster.of(flowContext)
.setResponseMessage(cmdInfo, boolValue);
// 广播 boolean list
List<Boolean> boolValueList = List.of(true, false);
RangeBroadcaster.of(flowContext)
.setResponseMessageBoolList(cmdInfo, boolValueList);
}
#301 FlowContext 更新元信息后,需要立即生效(跨服调用时)
在此之前,更新元信息后,并不会将元信息同步到 FlowContext 中,只会将元信息同步到游戏对外服中;所以在更新元信息后,紧接着执行跨服调用是不能获取新的元信息内容的。
当前 issues 会对这部分做增强,也就是在更新元信息后,会将元信息同步到 FlowContext 中;这样,在后续的跨服调用中也能获取到最新的元信息。
void test1(FlowContext flowContext) {
// 获取元信息
MyAttachment attachment = flowContext.getAttachment(MyAttachment.class);
attachment.nickname = "渔民小镇";
// [同步]更新 - 将元信息同步到玩家所在的游戏对外服中
flowContext.updateAttachment(attachment);
// 跨服请求
CmdInfo helloCmdInfo = CmdInfo.of(1, 1);
flowContext.invokeModuleMessage(helloCmdInfo);
}
@ActionController(1)
public class DemoFightAction {
@ActionMethod(1)
void hello(FlowContext flowContext) {
// 可以得到最新的元信息
MyAttachment attachment = flowContext.getAttachment(MyAttachment.class);
log.info("{}", attachment.nickname);
}
}
#293 广播文档构建器支持对参数的单独描述
private void extractedDco(BarSkeletonBuilder builder) {
// UserCmd
builder.addBroadcastDoc(BroadcastDoc.newBuilder(UserCmd.of(UserCmd.enterSquare))
.setDataClass(SquarePlayer.class)
.setDescription("新玩家加入房间,给房间内的其他玩家广播")
).addBroadcastDoc(BroadcastDoc.newBuilder(UserCmd.of(UserCmd.offline))
.setDataClass(LongValue.class, "userId")
.setDescription("有玩家下线了")
);
}
下面是生成后的对接文档预览
==================== 游戏文档格式说明 ====================
https://www.yuque.com/iohao/game/irth38#cJLdC
==================== FightHallAction 大厅(类似地图) ====================
路由: 1 - 2 --- 【进入大厅】 --- 【FightHallAction:94】【enterSquare】
方法参数: EnterSquare enterSquare 进入大厅
方法返回值: ByteValueList<SquarePlayer> 所有玩家
广播推送: SquarePlayer ,(新玩家加入房间,给房间内的其他玩家广播)
路由: 1 - 5 --- 【玩家下线】 --- 【FightHallAction:154】【offline】
方法返回值: void
广播推送: LongValue userId,(有玩家下线了)
[内置 kit]
开放 TaskListener 接口,TaskListener 是 TaskKit 相关的任务监听接口。
TaskListener 任务监听回调,使用场景有:一次性延时任务、任务调度、轻量可控的延时任务、轻量的定时入库辅助功能 ...等其他扩展场景。这些使用场景都有一个共同特点,即监听回调。接口提供了 4 个方法,如下
- CommonTaskListener.onUpdate(),监听回调
- CommonTaskListener.triggerUpdate(),是否触发 CommonTaskListener.onUpdate() 监听回调方法
- CommonTaskListener.onException(Throwable) ,异常回调。在执行 CommonTaskListener.triggerUpdate() 和 CommonTaskListener.onUpdate() 方法时,如果触发了异常,异常将被该方法捕获。
- CommonTaskListener.getExecutor(),指定执行器来执行上述方法,目的是不占用业务线程。
更多介绍与使用,请阅读 TaskKit (yuque.com)