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
834 stars 183 forks source link

逻辑服之间通过路由调用超时返回 null #304

Closed molin7596 closed 2 months ago

molin7596 commented 2 months ago

你的问题 | 使用场景

  1. 逻辑服之间通过路由调用超时 返回null(ResponseMessage is null),为什么不是返回超时异常信息
  2. 只是调用超时 (ResponseMessage)才会返回null吗? 还有其他情况会返回null吗?
  3. 一定要有返回值才能获取异常信息吗
iohao commented 2 months ago

逻辑服之间通过路由调用超时 返回null(ResponseMessage is null),为什么不是返回超时异常信息

远程调用失败返回 null,比如超时。其他异常参考 RemotingException, InterruptedException

具体请阅读相关源码 https://github.com/iohao/ioGame/blob/c3136b4ba1c8893fa3f35de1c341cc4d29dfc21f/net-bolt/bolt-core/src/main/java/com/iohao/game/bolt/broker/core/client/BrokerClientItem.java#L163-L176


其他不相关的问题,另开 issue 吧。

molin7596 commented 2 months ago

请求超时时 再次请求怎么样才能访问到上次同一个逻辑服(除开逻辑服只有一个这种情况)

iohao commented 2 months ago

请求超时时 再次请求怎么样才能访问到上次同一个逻辑服(除开逻辑服只有一个这种情况)

可以通过动态绑定游戏逻辑服特性来完成。

或参考 #192

molin7596 commented 2 months ago

这个我之前看过了 都是先绑定 在调用,有没有能够不先绑定也可以获取上次请求的的逻辑服id,是我这个想法不符合常理吗。通常不会这样做嘛

iohao commented 2 months ago

偏特定业务的需要自己处理,因为默认的实现是调用方不需要关心同类型逻辑服启动了多少个;只需要发送请求,其他游戏逻辑服能处理就行。

一般需要固定某个游戏逻辑服请求的,且频繁的;可以事先绑定好。如果是突然性的,不频繁的,可以参考下面的。

这个我之前看过了 都是先绑定 在调用,有没有能够不先绑定也可以获取上次请求的的逻辑服id

可以指定需要访问的游戏逻辑服 id,设置到 HeadMetadata 中,下面是两个示例代码

public void invokeModuleMessage(FlowContext flowContext) {
    // 设置 FlowContext 中的 HeadMetadata
    HeadMetadata headMetadata = flowContext.getHeadMetadata();
    int[] bindingLogicServerIds = new int[]{
            HashKit.hash32("指定访问的游戏逻辑服 id")
    };

    // 设置需要指定访问的游戏逻辑服 id
    headMetadata.setBindingLogicServerIds(bindingLogicServerIds);
    CmdInfo cmdInfo = ...
    ResponseMessage responseMessage = flowContext.invokeModuleMessage(cmdInfo);
}

public void invokeModuleMessage(CmdInfo cmdInfo, Object data) {
    // 创建一个模拟请求
    RequestMessage requestMessage = BarMessageKit.createRequestMessage(cmdInfo, data);
    HeadMetadata headMetadata = requestMessage.getHeadMetadata();
    // 设置需要模拟的 userId
    headMetadata.setUserId(100);

    int[] bindingLogicServerIds = new int[]{
            HashKit.hash32("指定访问的游戏逻辑服 id")
    };

    // 设置需要指定访问的游戏逻辑服 id
    headMetadata.setBindingLogicServerIds(bindingLogicServerIds);

    // 发起 action 调用
    InvokeModuleContext invokeModuleContext = BrokerClientHelper.getInvokeModuleContext();
    ResponseMessage responseMessage = invokeModuleContext.invokeModuleMessage(requestMessage);
}
molin7596 commented 2 months ago

好的,明白了 只能先设置逻辑服id 或者绑定