背景:
1.无论什么类型的游戏,我们都会有rpc通信的需求。
2.由于客户端直连的是游戏服,如果工会,匹配之类的服务是单独的服务的话,必然要进行游戏服到业务服之间的转发,我们是否需要再转发时单独定义Req和Res就是我们考虑到的需求。
3.在vega项目中,我们选择了定义了内部协议的req和res,而不是像热江一样做了统一的封装,看起来麻烦了一点,但是实际上却是非常的清晰。
一个案例如下:
1.发出rpc请求
// GuildService.java
getRecommendList方法:
// 向world服发送请求推荐列表(GuildBizModule.java进行RECOMMEND_LIST协议的处理)
BinaryMsg msg = buildBinaryMsg(GuildLogicEnum.RECOMMEND_LIST, role.getRid());
msg.writeInt(role.getLevel());
// 思考下我们的rpc需要什么参数
// 1.req 请求类型,这个我们希望是pb这种强类型的
// 2.rep.class 返回的类型
// 3.ResponseData<Boolean, Rep> 是否远端处理成功,有时候我们先本地扣东西,用于回滚
// 4.hashId 远端在哪个线程执行 我们一般采用类似于actor模型,因此需要告知远端到底在哪个线程执行
S2SHelper.sendMsg2WorldServer(msg, rid, BizType.GUILD,
Constants.BIZ_GUILD_DEFAULT_SUBKEY, new RespCacheCallback<>(role) {
@Override
public void onCallback(BinaryMsg msg) {
int result = msg.readInt();
if (result < 0) {
handlerError(role, requestId, msg);
return;
}
JSONObject json = msg.readObject(JSONObject.class);
// 这个是要返回给客户端的数据 setData是RespCacheCallback
setData(json);
}
});
// 其实,我也不太需要知道当前是哪个类,通过消息号范围即可
2.World进行业务端处理
GuildBizModule.java
processMsg方法:
switch (codeEnum) {
case RECOMMEND_LIST:
WSGuildService.recommendList(replyTo, rid, msg);
}