关于广播客户端监听的问题
MengLiuLei opened this issue · comments
MengLiuLei commented
我今天看了一天的文档,然后我们的业务逻辑大致是类似于,一个用户登陆,其他用户要能够知道所有用户的登陆,然后@ActionMethod的方法需要使用void广播的形式来给所有登陆成功用户的users发送相同的数组列表。然后我自己写了一个demo的method。
服务端代码:
@ActionMethod(DemoCmdForSpring.login)
public void login(DemoUserInfo userInfo, FlowContext flowContext) {
DemoUserInfo newUserInfo = new DemoUserInfo();
String phone = userInfo.phone;
long id = Long.parseLong(phone);
UserIdSettingKit.settingUserId(flowContext,id);
longs.add(id);
BroadcastContext broadcastContext = BrokerClientHelper.getBroadcastContext();
newUserInfo.phone = "链接成功,当前有用户:" + JSONArray.toJSONString(longs);
CmdInfo cmdInfo = CmdInfo.of(DemoCmdForSpring.cmd, DemoCmdForSpring.login);
broadcastContext.broadcast(cmdInfo,newUserInfo,longs);
}
然后使用InternalRegion1 来监听:
static class InternalRegion1 extends AbstractInputCommandRegion {
@Override
public void initInputCommand() {
inputCommandCreate.cmd = DemoCmdForSpring.cmd;
ofListen(result -> {
DemoUserInfovalue = result.getValue(DemoUserInfo.class);
log.info("broadcastMessage ========== \n{}", value);
}, DemoCmdForSpring.login, "login");
}
}
使用LoginOne来进行发送消息:
static class LoginOne extends AbstractInputCommandRegion {
@Override
public void initInputCommand() {
inputCommandCreate.cmd = DemoCmdForSpring.cmd;
ofCommand(DemoCmdForSpring.login).setTitle("login").setRequestData(() -> {
DemoUserInfo userInfo = new DemoUserInfo();
userInfo.setPhone("1");
return userInfo;
}).callback(result -> {
DemoCmdForSpring value = result.getValue(DemoCmdForSpring.class);
log.info("value : {}", value);
});
// 一秒后,执行模拟请求;
TaskKit.runOnceSecond(() -> {
// 执行 here 请求
ofRequestCommand(DemoCmdForSpring.login).execute();
});
}
}
我发现消息发送成功了,但是InternalRegion1 一只监听不到数据,服务端有打印成功:
┏━━━━━ 广播. [(DemoSpringAction.java:80)] ━━━ [cmd:2 - subCmd:1 - cmdMerge:131073]
┣ userId: [1, 1, 1]
┣ 广播数据: DemoUserInfo(phone=链接成功,当前有用户:[1,1,1], password=null)
┣ 广播时间: 2024-05-09 18:06:28.975
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
所以这个广播我有些没有明白耶,麻烦可以解答下吗?
渔民小镇 commented
你的代码看上去似乎是没问题的,但在实际中没有尝试过将相同路由分开成两个类来编写的(即 LoginOne、InternalRegion1)。
或许你可以尝试将相同路由的请求与广播监听写在同一个模拟类中,如下
public class DemoRegion extends AbstractInputCommandRegion {
static final Logger log = LoggerFactory.getLogger(DemoRegion.class);
@Override
public void initInputCommand() {
// 模拟请求的主路由
inputCommandCreate.cmd = DemoCmd.cmd;
ofCommand(DemoCmd.login).setTitle("login").setRequestData(() -> {
return LongValue.of(100);
});
// ---------------- 广播监听 ----------------
ofListen(result -> {
HelloReq value = result.getValue(HelloReq.class);
log.info("value : {}", value);
}, DemoCmd.login, "login");
TaskKit.runOnceSecond(() -> {
ofRequestCommand(DemoCmd.login).execute();
});
}
}
@ActionController(DemoCmd.cmd)
public class DemoAction {
@ActionMethod(DemoCmd.login)
public void login(long userId, FlowContext flowContext) {
UserIdSettingKit.settingUserId(flowContext, userId);
CmdInfo cmdInfo = CmdInfo.of(DemoCmd.cmd, DemoCmd.login);
HelloReq helloReq = new HelloReq();
helloReq.name = "aaa : " + userId;
// 全服广播
flowContext.broadcast(cmdInfo, helloReq);
}
}
MengLiuLei commented
感谢,整明白了