GM 后台与逻辑服交互
介绍
有时候,我们需要在其他系统中与游戏逻辑服交互。 比如通过 GM 后台实现充值回调,或给玩家发送一些消息 ...等。 换句话说,就是如何在其他系统中调用游戏逻辑服的 action。
不同系统之间的交互,需要协议一致。 比如,当对方使用 http 协议对外提供 api 时,那么我们只能使用 http 协议的方式去访问对方。 当对方使用 MQ 协议时,我们只能使用符合其 MQ 协议的方式去访问对方。 当对方使用 Redis 协议时,我们只能使用符合其协议的方式去访问对方。
在你使用第三方的服务时,通常会看见很多第三方的服务提供方会提供的各种 xxxClientSDK, 其目的是为了让服务使用方能够使用符合其协议的方式与其通信,如各种 xxxMQClientSDK、xxxRedisClientSDK 等。 无论服务提供方的 api 是以什么样的方式提供的,我们只需要符合其协议规范就能与其通信。
当其他系统想与 ioGame 交互时,只需要在其项目中启动一个 ioGame 逻辑服,就能与其他的逻辑服和玩家交互了。 ioGame 的逻辑服(BrokerClient)是轻量级的,在本质上是一个 netty client 连接。 所以,即使你在一个进程中启动了数百个逻辑服那也是轻量的。
示例介绍
现在,我们简单的介绍一个 GM 后台与 ioGame 其他逻辑服交互的方式。
- 外部通信,我们使用 http 对外提供 api,用于接收第三方平台的回调。
- 内部通信,与逻辑服中的玩家交互。
本篇文档将使用 web 项目来访问 action,后续称该 web 项目为 GM 后台。 GM 后台提供两个接口,分别是
- 充值回调。
- 给玩家发送一个消息。
整体流程为 : 访问 URL --> GM 后台处理该 http 请求 --> 在 web mvc controller 中模拟一个玩家请求, 并将数据传递到逻辑服的 action 处理 --> 之后在 action 中通知玩家。
Example Source Code
see https://github.com/iohao/ioGameExamples
path : SimpleExample/example/example-exchange
- ExchangeGameApplication
- GameManagerApplication
- ExchangeClient
当我们将项目启动后,在浏览器输入
- http://localhost:8080/gm/notice 触发 notice 方法。
- http://localhost:8080/gm/recharge 触发 recharge 方法。
之后分别观察 ExchangeGameApplication、GameManagerApplication、ExchangeClient 对应的控制台。 当我们访问 GM 后台提供的 URL 后,就能在模拟客户端 ExchangeClient 的控制台中看到相关数据。
关键代码说明
游戏逻辑服
方法说明
- internalRecharge,GM 后台接收到充值回调后会调用此方法,开发者可在此方法内做添加游戏金币的逻辑。
- internalNotice,通过 GM 后台,给玩家发送一条消息。
@ActionController(ExchangeCmd.cmd)
public class ExchangeAction {
...
@ActionMethod(ExchangeCmd.recharge)
public String internalRecharge(long money, FlowContext flowContext) {
long userId = flowContext.getUserId();
log.info("userId:{}, recharge:{}", userId, money);
flowContext.broadcastMe(LongValue.of(money));
return "userId:%s, recharge %s".formatted(userId, money);
}
@ActionMethod(ExchangeCmd.notice)
public void internalNotice(String message, FlowContext flowContext) {
long userId = flowContext.getUserId();
log.info("userId:{}, message:{}", userId, message);
flowContext.broadcastMe(StringValue.of(message));
}
}
GM 后台
GM 后台是 web 项目,Controller 中演示了如何调用 action。
notice 方法
在浏览器输入 http://localhost:8080/gm/notice 可触发 notice 方法。
方法中使用 RequestMessage 来模拟一个玩家请求,并通过 BrokerClient 对象调用 action。 之后会触发游戏逻辑服的 ExchangeAction.internalNotice 方法。
recharge 方法
在浏览器输入 http://localhost:8080/gm/recharge 可触发 recharge 方法。
方法中,我们通过 UserFlowContext 来模拟玩家请求,UserFlowContext 是我们扩展的一个类,该类继承了 FlowContext。
当调用 userFlowContext.invokeModuleMessage 后,将会触发游戏逻辑服的 ExchangeAction.internalRecharge 方法。
- code 14~15,创建模拟请求,并设置需要模拟的玩家
- code 17~18,向游戏逻辑服发送请求
- code 28~29,模拟玩家请求,并向游戏逻辑服发送请求
- code 34,获取游戏逻辑服响应的数据。
@Slf4j
@RestController
@RequestMapping("gm")
public class GameManagerController {
static final AtomicLong msgId = new AtomicLong();
static final long userId = 1;
@GetMapping("/notice")
public String notice() {
long id = msgId.incrementAndGet();
String msg = "GM web message " + id;
var noticeCmd = ExchangeCmd.of(ExchangeCmd.notice);
RequestMessage requestMessage = BarMessageKit.createRequestMessage(noticeCmd, StringValue.of(msg));
requestMessage.getHeadMetadata().setUserId(userId);
BrokerClient brokerClient = MyKit.brokerClient;
brokerClient.getInvokeModuleContext().invokeModuleVoidMessage(requestMessage);
return "notice: " + id;
}
@GetMapping("/recharge")
public String recharge() {
var rechargeCmd = ExchangeCmd.of(ExchangeCmd.recharge);
long money = RandomKit.random(1, 1000);
UserFlowContext userFlowContext = MyKit.ofUserFlowContext(userId);
ResponseMessage responseMessage = userFlowContext.invokeModuleMessage(rechargeCmd, LongValue.of(money));
if (responseMessage.hasError()) {
return "recharge error";
}
String data = responseMessage.getString();
return "recharge: " + data;
}
}
GM 逻辑服 保存逻辑服实例引用。
public class GameManagerLogicServer extends AbstractBrokerClientStartup {
...
@Override
public void startupSuccess(BrokerClient brokerClient) {
MyKit.brokerClient = brokerClient;
MyKit.barSkeleton = brokerClient.getBarSkeleton();
}
}
小结
本文虽然只介绍了 web 项目如何与 ioGame 交互,方法也比较简单, 就是在 web 项目中启动一个【GM 逻辑服】,通过该逻辑服就能与 ioGame 其他逻辑服和玩家交互了。
现在,我们的 GM 后台具备了 http 和内部通信的能力,对外可以提供 http 给三方使用,对内又能与其他逻辑服和玩家交互。 http 的能力是由 SpringMVC 提供的,而内部通信的能力则是【GM 逻辑服】提供的。
GM 后台几乎是游戏服务器必备的一个模块,该模块存在的意义有以下几个方面
- 接收其他平台的 http 回调,如充值 ... 等。
- 与内部其他逻辑服通信、与玩家通信。
- GM 系统的其他辅助功能。