iohao / ioGame

无锁异步化、事件驱动架构设计的 java netty 网络编程框架; 轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式; 适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景; 通过 ioGame 你可以很容易的搭建出一个集群无中心节点、集群自动化、分布式的网络服务器;FXGL、Unity、UE、Cocos Creator、Godot、Netty、Protobuf、webSocket、tcp、socket;java Netty 游戏服务器框架;
http://game.iohao.com
GNU Affero General Public License v3.0
904 stars 201 forks source link

通过ClientRunOne方式模拟玩家行为,希望提供一些新的属性或者监听器去触发自定义逻辑 #259

Closed 853603855 closed 6 months ago

853603855 commented 7 months ago

Eg,我通过new ClientRunOne().idle(5).startup()的方式启动一个持续心跳的线程去模拟玩家的行为,当达到一定条件后,希望当前玩家(线程)能主动断开连接。

iohao commented 7 months ago

未来可能的示例,框架会提供 Simple_XXX_Property 系列,该系列的相关实现会有 int、long、boolean、String 等实现类,并结合现有的动态属性来实现扩展。

Simple_XXX_Property 系列支持添加监听,当值有变动时会触发监听,开发者可在监听中做扩展;

下面是使用示例。

// attr name
final AttrOption<SimpleIntegerProperty> ageOption = AttrOption.valueOf("age");
// 模拟的玩家
ClientUser clientUser = ...;

private void extracted() {
    // the age is SimpleIntegerProperty;(Simple_XXX_Property 系列)    
    SimpleIntegerProperty age = clientUser.option(ageOption);
    // age 添加监听
    age.addListener((observable, oldValue, newValue) -> {
        log.info("value : {} - {}", oldValue, newValue);

        if (newValue.intValue() > 2) {
            // ... 执行其他自定义逻辑,如关闭 channel 等
            // clientUser.close();
        }
    });

    // 设置值,value = 1
    age.setValue(1);
    // 添加值,value = 21,触发监听逻辑
    age.addValue(20);
}

// attr name
final AttrOption<SimpleIntegerProperty> idleOption = AttrOption.valueOf("idle");
private void extracted() {
    // the idle is SimpleIntegerProperty;(Simple_XXX_Property 系列)   
    SimpleIntegerProperty idle = clientUser.option(idleOption);
    // idle 添加监听
    idle.addListener((observable, oldValue, newValue) -> {
        log.info("idle value : {} - {}", oldValue, newValue);

        if (newValue.intValue() > 20) {
            // ... 执行其他自定义逻辑,如关闭 channel 等
            // clientUser.close();
        }
    });
}
853603855 commented 7 months ago

OK,解决方案都非常到位

iohao commented 6 months ago

264

扩展示例参考

public class DemoHookClient {
    public static void main(String[] args) {
        int idlePeriod = 3;
        // 模拟的玩家
        var clientUser = getDefaultClientUser(idlePeriod);

        // 启动模拟客户端
        new ClientRunOne()
                .setClientUser(clientUser)
                // 开启心跳,每 N 秒向服务器发送一次心跳消息
                .idle(idlePeriod)
                .startup();
    }

    private static DefaultClientUser getDefaultClientUser(int idlePeriod) {
        // 动态属性 key
        AttrOption<IntegerProperty> idleOption = AttrOption.valueOf("idleOption");
        // 模拟的心跳计数器
        IntegerProperty idleCounter = new IntegerProperty();
        // 添加一个监听器,当值发生变化时会触发监听器
        idleCounter.addListener((observable, oldValue, newValue) -> {
            if (newValue.intValue() > 10) {
                // 其他逻辑,关闭模拟客户端连接
                clientUser.getClientUserChannel().closeChannel();
            }
        });

        // 给 clientUser 添加一个动态属性
        var clientUser = new DefaultClientUser();
        clientUser.option(idleOption, idleCounter);

        // 每 N 秒执行一次
        TaskKit.runInterval(() -> {
            // 心跳计数器 + 1,每次值变更,并触发监听
            clientUser.ifPresent(idleOption, IntegerProperty::increment);
        }, idlePeriod, TimeUnit.SECONDS);

        return clientUser;
    }
}
iohao commented 6 months ago

https://github.com/iohao/ioGame/releases/tag/21.6