Skip to content

Commit

Permalink
🐳 [动态属性] 增加 ifNull 方法,如果动态属性值为 null,则执行给定的操作,否则不执行任何操作。执行给定操作后将得到一个返回…
Browse files Browse the repository at this point in the history
…值,该返回值会设置到动态属性中。

Runner 机制相关 javadoc 补充

整理示例文档相关内容
  • Loading branch information
iohao committed Jun 5, 2024
1 parent f99ba12 commit aff3b6a
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 46 deletions.
45 changes: 16 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ ioGame 支持申请盈利后支付闭源授权费,收入不超过10万人民

---



### 启动展示

ioGame 在内存占用、启动速度、打包等方面也是优秀的。
Expand Down Expand Up @@ -166,16 +164,17 @@ ioGame 在内存占用、启动速度、打包等方面也是优秀的。

**示例**

| **示例** | |
| ------------------------------------------------------------ | ------------------------------------------------------- |
| [u3d 连接示例文档](https://www.yuque.com/iohao/game/syv5mm) | 已经与 ioGame 的综合示例联调成功 |
| [cocosCreator 连接示例文档](https://www.yuque.com/iohao/game/ua4afq) | 已经与 ioGame 的综合示例联调成功 |
| [UE5 连接示例文档](https://www.yuque.com/iohao/game/rus213) | 已经与 ioGame 的综合示例联调成功 |
| [unity Tcp 移动同步 demo](https://www.yuque.com/iohao/game/kswsfk13ocg069uf) | 提供了 unity 与 ioGame 的【多人】移动同步演示 |
| [websocket.js 连接示例文档](https://www.yuque.com/iohao/game/knqxehz2pl1sal5s) | websocket.js 连接的一个示例,使用 json 协议来传输交互。 |
| | |
| [fxgl-ioGame-移动同步](https://www.yuque.com/iohao/game/bolt) | FXGL + ioGame 网络游戏中的多人移动演示。 |
| [ioGame 综合示例介绍](https://www.yuque.com/iohao/game/ruaqza) | 示例中有功能特性的实践、打包部署(docker、k8s)等介绍 |
| 示例 | 描述 |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [ioGame 综合示例介绍](https://www.yuque.com/iohao/game/ruaqza) | 示例中有功能特性的实践、打包部署(docker、k8s)等介绍 |
| [[示例] FXGL 连接示例;Protobuf、java、Netty](https://www.yuque.com/iohao/game/bolt) | FXGL + ioGame 网络游戏中的多人移动演示 |
| [[示例] Unity 连接示例 - 1;Protobuf、C#、Netty](https://www.yuque.com/iohao/game/syv5mm) | unity3d 连接示例 websocket + protobuf(已经与综合示例调通) |
| [[示例] Unity 连接示例 - 2;Protobuf、C#、Netty](https://www.yuque.com/iohao/game/kswsfk13ocg069uf) | 提供了 unity 与 ioGame 的【多人】移动同步演示 |
| [[示例] Cocos Creator 连接示例;Protobuf、TypeScript、Netty](https://www.yuque.com/iohao/game/ua4afq) | cocosCreator 连接示例 websocket + protobuf(已经与综合示例调通) |
| [[示例] Godot 连接示例;Protobuf、C#、Netty](https://www.yuque.com/iohao/game/ci9ebb3cztpbhsbm) | 网络通信使用 webSocket |
| [[示例] UE5 连接示例;Protobuf、C++、Netty](https://www.yuque.com/iohao/game/rus213) | UE5 连接示例 websocket + protobuf(已经与综合示例调通) |
| [[示例] JavaScript 连接示例;json、JavaScript、Netty](https://www.yuque.com/iohao/game/knqxehz2pl1sal5s) | 使用 websocket.js 来连接 ioGame 的一个示例,使用 json 协议来传输交互。 |
| [[示例] TypeScript 连接示例;json、TypeScript、Netty](https://www.yuque.com/iohao/game/wbsnir210c4xtpyp) | 使用 json 协议来传输交互。 |



Expand Down Expand Up @@ -1112,9 +1111,7 @@ action 处理逻辑时,使用是就是这种通讯方式。将数据 return

![img](https://raw.githubusercontent.com/iohao/ioGameResource/main/images/interaction.jpg)



> 抽象的说,游戏前端与游戏服务器的的交互由上图组成。游戏前端与游戏服务器可以自由地双向交互,即发送和接收业务数据。业务数据由.proto文件作为载体,在前端和后端之间进行编码和解码。.proto文件是对业务数据的描述载体,定义了数据类型和消息类型,以及它们的属性和规则。
> 抽象的说,游戏前端与游戏服务器的的交互由上图组成。游戏前端与游戏服务器可以自由地双向交互,即发送和接收业务数据。业务数据由 .proto 文件作为载体,在前端和后端之间进行编码和解码。.proto 文件是对业务数据的描述载体,定义了数据类型和消息类型,以及它们的属性和规则。
>
>
>
Expand All @@ -1130,15 +1127,15 @@ action 处理逻辑时,使用是就是这种通讯方式。将数据 return
>
> **游戏前端**
>
> 游戏前端的展现可以是 [Unity](https://unity.cn/)[UE(虚幻)](https://www.unrealengine.com/zh-CN/)[Cocos](https://www.cocos.com/)[FXGL](https://github.com/AlmasB/FXGL) 或者其他的游戏引擎。这些游戏引擎只是展现游戏画面的一种形式,数据交互则由通信来完成(TCP、UDP 等)。游戏前端可以是 [Unity](https://unity.cn/)[UE(虚幻)](https://www.unrealengine.com/zh-CN/)[Cocos](https://www.cocos.com/)[FXGL](https://github.com/AlmasB/FXGL) 或者其他的游戏引擎。
> 游戏前端的展现可以是 [Unity](https://unity.cn/)[UE](https://www.unrealengine.com/zh-CN/)[Cocos Creator](https://www.cocos.com/)[FXGL](https://github.com/AlmasB/FXGL)[Godot](https://godotengine.org/) 或者其他的游戏引擎。这些游戏引擎只是展现游戏画面的一种形式,数据交互则由通信来完成(TCP、UDP 等)。
<br>

**快速入门代码示例**

> 这里主要介绍游戏服务器相关的,下面这个示例介绍了服务器编程可以变得如此简单。

<br>

**协议文件定义**

Expand All @@ -1157,8 +1154,6 @@ public class HelloReq {
}
```



<br>

**Action**
Expand Down Expand Up @@ -1491,12 +1486,10 @@ public class RoomNumMsg {

## 参考

什么是 [Action](https://www.yuque.com/iohao/game/sqcevl)
什么是 [Action](https://www.yuque.com/iohao/game/sqcevl)

[快速从零编写服务器完整示例](https://www.yuque.com/iohao/game/zm6qg2)

[坦克示例](https://www.yuque.com/iohao/game/gqossg) (游戏前端)

[广播(推送)相关示例与文档](https://www.yuque.com/iohao/game/qv4qfo)

[逻辑服与逻辑服之间的交互示例](https://www.yuque.com/iohao/game/anguu6)
Expand All @@ -1505,12 +1498,6 @@ public class RoomNumMsg {



[u3d 连接示例](https://www.yuque.com/iohao/game/syv5mm)

[cocosCreator 连接示例](https://www.yuque.com/iohao/game/ua4afq)



## 安装与使用ioGame

参考 https://www.yuque.com/iohao/game/wsgmba
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public BarSkeletonBuilder addInOut(ActionMethodInOut inOut) {
}

/**
* 添加 Runner
* 添加 Runner 机制,会在逻辑服与 Broker(游戏网关)建立连接之前(onStart)、之后(onStartAfter)分别触发一次。
*
* @param runner Runner
* @return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,85 @@
import com.iohao.game.action.skeleton.core.BarSkeleton;

/**
* Runner 机制
* Runner 机制,会在逻辑服与 Broker(游戏网关)建立连接之前(onStart)、之后(onStartAfter)分别触发一次。<a href="https://www.yuque.com/iohao/game/dpwe6r6sqwwtrh1q">相关文档</a>
* <pre>
* 1.在逻辑服与 Broker(游戏网关)建立连接之前调用一次,触发 {@link Runner#onStart(BarSkeleton)} 方法。
* 2.在逻辑服将信息注册到 Broker(游戏网关)后调用一次,触发 {@link Runner#onStartAfter(BarSkeleton)} 方法。
* </pre>
* for example
* <pre>{@code
* // 路由访问权限以 Runner 机制扩展
* public class ExternalAccessAuthenticationRunner implements Runner {
* @Override
* public void onStart(BarSkeleton skeleton) {
*
* <pre>会在逻辑服启动后触发 Runner 机制</pre>
* var accessAuthenticationHook = ExternalGlobalConfig.accessAuthenticationHook;
* // 表示登录才能访问业务方法
* accessAuthenticationHook.setVerifyIdentity(true);
* // 添加不需要登录(身份验证)也能访问的业务方法 (action)
* accessAuthenticationHook.addIgnoreAuthenticationCmd(1, 1);
* // 添加不需要登录(身份验证)也能访问的主路由(范围)
* accessAuthenticationHook.addIgnoreAuthenticationCmd(2);
*
* // 拒绝主路由为 10 的访问请求
* accessAuthenticationHook.addRejectionCmd(10);
* // 拒绝主路由为 11、子路由为 1 的访问请求
* accessAuthenticationHook.addRejectionCmd(11, 1);
* }
* }
*
* // 游戏对外服
* public class MyExternalServer extends ExternalBrokerClientStartup {
* @Override
* public BarSkeleton createBarSkeleton() {
* // 游戏对外服不需要业务框架,这里给个空的
* BarSkeletonBuilder builder = BarSkeleton.newBuilder();
*
* // 路由访问权限以 Runner 机制扩展
* builder.addRunner(new ExternalAccessAuthenticationRunner());
*
* return builder.build();
* }
* }
* }
* </pre>
* for example
* <pre>{@code
* BarSkeletonBuilder builder = ...
*
* builder.addRunner(new Runner() {
* @Override
* public void onStart(BarSkeleton skeleton) {
* log.info("在逻辑服与 Broker(游戏网关)建立连接之前调用一次");
* }
*
* @Override
* public void onStartAfter(BarSkeleton skeleton) {
* log.info("在逻辑服与 Broker(游戏网关)建立连接之后调用一次");
* }
* });
*
* }
* </pre>
*
* @author 渔民小镇
* @date 2023-04-23
*/
public interface Runner {
/**
* 启动
* 在逻辑服与 Broker(游戏网关)建立连接之前调用一次。
* <pre>
* 框架会在逻辑服启动后调用一次
* 此时还不能与 Broker(游戏网关)通信。
* </pre>
*
* @param skeleton 业务框架
*/
void onStart(BarSkeleton skeleton);

/**
* 启动
* 在逻辑服与 Broker(游戏网关)建立连接之后调用一次。
* <pre>
* 框架会在逻辑服启动后调用一次,会在逻辑服将信息注册到 Broker(游戏网关)后触发。
* 可以与 Broker(游戏网关)通信了。
*
* 如果没有特殊需求的,使用 onStart 方法就可以了。
* </pre>
*
Expand All @@ -61,4 +116,4 @@ default void onStartAfter(BarSkeleton skeleton) {
default String name() {
return this.getClass().getName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@
import java.util.stream.Collectors;

/**
* Runners 管理器
*
* @author 渔民小镇
* @date 2023-04-23
* @see Runner
*/
@FieldDefaults(level = AccessLevel.PRIVATE)
public final class Runners {
Expand Down Expand Up @@ -74,11 +77,15 @@ public void onStart() {

/** 启动 runner 机制 onStartAfter 方法 */
public void onStartAfter() {
if (this.onStartAfter.get()) {
return;
}

if (this.onStartAfter.compareAndSet(false, true)) {
TaskKit.newTimeout(timeout -> {
TaskKit.runOnceSecond(() -> {
// 延迟 1 秒执行,防止没连接到服务器, 或者将来增加一个注册回调的 Processor,目前先暂时这样
this.runnerList.forEach(runner -> runner.onStartAfter(this.barSkeleton));
}, 1, TimeUnit.SECONDS);
});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* ioGame
* Copyright (C) 2021 - present 渔民小镇 ([email protected][email protected]) . All Rights Reserved.
* # iohao.com . 渔民小镇
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* {@link com.iohao.game.action.skeleton.core.runner.Runner} 机制类似于 Spring CommandLineRunner 的启动项,它能够在逻辑服务器启动之后调用一次 Runner 接口实现类,让开发者能够通过实现 Runner 接口来扩展自身的系统。
* <p>
* Runner 机制,会在逻辑服与 Broker(游戏网关)建立连接之前、之后分别触发一次对应的方法。<a href="https://www.yuque.com/iohao/game/dpwe6r6sqwwtrh1q">相关文档</a>
*
* @author 渔民小镇
* @date 2024-06-05
*/
package com.iohao.game.action.skeleton.core.runner;
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import com.iohao.game.action.skeleton.core.action.ExampleActionCmd;
import com.iohao.game.action.skeleton.core.action.pojo.BeeApple;
import com.iohao.game.action.skeleton.core.data.TestDataKit;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;

@Slf4j
public class BarSkeletonTest {
BarSkeleton barSkeleton;

Expand Down Expand Up @@ -72,5 +74,4 @@ public void testVoid() {
barSkeleton.handle(flowContext);
System.out.println();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* 动态属性 (类型明确的)
Expand Down Expand Up @@ -107,7 +108,7 @@ default <T> AttrOptions option(AttrOption<T> option, T value) {
* 如果动态属性存在,则执行给定的操作,否则不执行任何操作。
*
* @param option option
* @param consumer 给定操作。只有 option 的值存在且不为 null 时,才会执行的操作。
* @param consumer 给定的操作。只有 option 的值存在且不为 null 时,才会执行的操作。
* @param <T> t
*/
default <T> void ifPresent(AttrOption<T> option, Consumer<T> consumer) {
Expand All @@ -116,4 +117,18 @@ default <T> void ifPresent(AttrOption<T> option, Consumer<T> consumer) {
consumer.accept(data);
}
}

/**
* 如果动态属性值为 null,则执行给定的操作,否则不执行任何操作。执行给定操作后将得到一个返回值,该返回值会设置到动态属性中。
*
* @param option option
* @param supplier 给定的操作。当 option 的值为 null 时,才会执行的操作
* @param <T> t
*/
default <T> void ifNull(AttrOption<T> option, Supplier<T> supplier) {
T data = this.option(option);
if (Objects.isNull(data)) {
this.option(option, supplier.get());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.iohao.game.common.kit.attr;

import lombok.Getter;
import org.junit.Assert;
import org.junit.Test;

/**
* @author 渔民小镇
* @date 2024-06-05
*/
public class AttrOptionDynamicTest {

final MyAttrOptions myAttrOptions = new MyAttrOptions();

AttrOption<AttrCat> catAttrOption = AttrOption.valueOf("AttrCat");

@Test
public void ifNull() {
Assert.assertNull(myAttrOptions.option(catAttrOption));

myAttrOptions.ifNull(catAttrOption, AttrCat::new);
Assert.assertNotNull(myAttrOptions.option(catAttrOption));

myAttrOptions.option(catAttrOption, null);
Assert.assertNull(myAttrOptions.option(catAttrOption));

AttrCat attrCat = new AttrCat();
attrCat.name = "a";
myAttrOptions.option(catAttrOption, attrCat);
myAttrOptions.ifNull(catAttrOption, AttrCat::new);
Assert.assertEquals(myAttrOptions.option(catAttrOption).name, attrCat.name);
}

private static class AttrCat {
String name;
}

@Getter
private static class MyAttrOptions implements AttrOptionDynamic {
final AttrOptions options = new AttrOptions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ public void defaultSetting(ExternalCoreSetting coreSetting) {
PresentKit.ifNull(idleHook, () -> idleProcessSetting.setIdleHook(new DefaultSocketIdleHook()));

// 心跳钩子 Handler
setting.option(SettingOption.socketIdleHandler, new SocketIdleHandler());
setting.ifNull(SettingOption.socketIdleHandler, SocketIdleHandler::new);
}

// pipelineCustom Handler
setting.option(SettingOption.socketUserSessionHandler, new SocketUserSessionHandler());
setting.option(SettingOption.socketCmdAccessAuthHandler, new SocketCmdAccessAuthHandler());
setting.option(SettingOption.socketRequestBrokerHandler, new SocketRequestBrokerHandler());
setting.ifNull(SettingOption.socketUserSessionHandler, SocketUserSessionHandler::new);
setting.ifNull(SettingOption.socketCmdAccessAuthHandler, SocketCmdAccessAuthHandler::new);
setting.ifNull(SettingOption.socketRequestBrokerHandler, SocketRequestBrokerHandler::new);
}
}

0 comments on commit aff3b6a

Please sign in to comment.