采用用同步编程的方式实现跨进程异步获取数据[一]
2013-09-14 17:59
786 查看
转载请注明:http://blog.csdn.net/herm_lib/article/details/11686483
异步获取数据,我这边采用了一点点小技巧,这样异步获取数据的操作,变成和同步操作一样自然。
这个我个人得静下心来,好好地梳理一下,过个半个月遇到类似的需求,我自己都忘记是怎么处理了。处理方式比较有意思。
遇到一些常见的异步操作的业务逻辑:
[1] 角色登录请求,发现内存中没有该角色数据,从远程的缓存或者DB读取该角色数据。
[2] 获取某个角色信息,发现这个角色信息目前不在线,这时候,也从远程的缓存或者db读取该角色数据。
[3] 判断这个家伙是否是另外一个玩家的好友,sns类游戏中,这类逻辑超多。
我们先把直接做法,简单列出来,用来和另外一种比较优雅的方式做比较。
术语定义:
Juge_Friend_Req
判断是否是好友的请求,发向好友服务器。
Juge_Friend_Res
从好友服务器回来。
Add_Energy_Req
从Client发过来的加能量的请求。
以[3]为例子,当然,好友服务器和主逻辑服务器是位于两个进程中,如果一个进程中,那没什么好说的。比如,给好友加能量,借好友宠物上场战斗。
从好友服务器回来的回应,以后有和好友判断相关的逻辑,会继续加新的业务分支。
这代码比较恶心,我们目标是,判断好友的回应回来后,我们的流程能继续回到各自请求的处理逻辑里去!从我们写代码的角度,就好像没有发生过异步请求。
我就记录一下,我们这边的处理方法。针对Add_Energe_Req的处理:
[1] 发出Judge_Friend_Req的时,把请求消息的内容,作为透传数据,发给好友服务器,然后就还回来,[4]用到。
[2] 引入一个附加参数,void* param,每个请求,各自转化自己的数据类型(这个描述不清楚)。
[3] 好友服务器回来消息,将消息分发给JudgeFriendRes的时候,设置上面那个param。
[4] 在Judge_Friend_Req时,有Add_Energe_Req的数据,想办法再一次分发Add_Energe_Req,重走一回AddEnergeReq流程。
发出好友请求和处理逻辑,两者是在一起的。
发判断好友请求时,msgReq设置成透传;根据param是否是nullptr来判定是否已经发过Judge_Friend_Req。
如果借用宠物的逻辑,和这个类似,各自写自己的逻辑。
Judge_Friend_Res回来时,做的工作。先在网络消息的分发的时候,做一些手脚,设置附加参数。
在JugdeFriendRes里,设置param
设置这个参数后,DispatchCS用透传的数据,让流程继续回到AddEnergyReq。当第2次走到AddEnergyReq时,param != nullptr,直接判定是否是好友,接下来做该做的事情。
异步获取数据,我这边采用了一点点小技巧,这样异步获取数据的操作,变成和同步操作一样自然。
这个我个人得静下心来,好好地梳理一下,过个半个月遇到类似的需求,我自己都忘记是怎么处理了。处理方式比较有意思。
遇到一些常见的异步操作的业务逻辑:
[1] 角色登录请求,发现内存中没有该角色数据,从远程的缓存或者DB读取该角色数据。
[2] 获取某个角色信息,发现这个角色信息目前不在线,这时候,也从远程的缓存或者db读取该角色数据。
[3] 判断这个家伙是否是另外一个玩家的好友,sns类游戏中,这类逻辑超多。
我们先把直接做法,简单列出来,用来和另外一种比较优雅的方式做比较。
术语定义:
Juge_Friend_Req
判断是否是好友的请求,发向好友服务器。
Juge_Friend_Res
从好友服务器回来。
Add_Energy_Req
从Client发过来的加能量的请求。
以[3]为例子,当然,好友服务器和主逻辑服务器是位于两个进程中,如果一个进程中,那没什么好说的。比如,给好友加能量,借好友宠物上场战斗。
void AddEnergyReq(roleId1, roleId2) { // 向好友服务器发出判断是否是好友的请求 JudgeFriendReq(roleId1, roleId2, kFriendBehaviorTypeAddEnergy); } void BorrowPetReq(roleId1, roleId2, petId) { JudgeFriendReq(roleId1, roleId2, kFriendBehaviorTypeBorrowPet); } // 从好友服务器回来判断是否是好友的回应 void JudgeFriendRes(msg) { switch (msg.operType) { case kFriendBehaviorTypeAddEnergy: AddEnergy(msg.xxx); break; case kFriendBehaviorTypeBorrowPet: BorrowPet(msg.xxx); break; } }
从好友服务器回来的回应,以后有和好友判断相关的逻辑,会继续加新的业务分支。
这代码比较恶心,我们目标是,判断好友的回应回来后,我们的流程能继续回到各自请求的处理逻辑里去!从我们写代码的角度,就好像没有发生过异步请求。
我就记录一下,我们这边的处理方法。针对Add_Energe_Req的处理:
[1] 发出Judge_Friend_Req的时,把请求消息的内容,作为透传数据,发给好友服务器,然后就还回来,[4]用到。
[2] 引入一个附加参数,void* param,每个请求,各自转化自己的数据类型(这个描述不清楚)。
[3] 好友服务器回来消息,将消息分发给JudgeFriendRes的时候,设置上面那个param。
[4] 在Judge_Friend_Req时,有Add_Energe_Req的数据,想办法再一次分发Add_Energe_Req,重走一回AddEnergeReq流程。
发出好友请求和处理逻辑,两者是在一起的。
void AddEnergyReq(msgReq, const Param* param) { if (!param) // param如果是nullptr, 还没有发过判断好友请求 // 向好友服务器发出判断是否是好友的请求 JudgeFriendReq(msgReq.roleId1, msgReq.roleId2, msgReq); else { bool isFriend = (bool)param; if (isFriend) AddEnergy(...); } }
发判断好友请求时,msgReq设置成透传;根据param是否是nullptr来判定是否已经发过Judge_Friend_Req。
如果借用宠物的逻辑,和这个类似,各自写自己的逻辑。
Judge_Friend_Res回来时,做的工作。先在网络消息的分发的时候,做一些手脚,设置附加参数。
void MsgDispatch(buf, len) { ssMsg = ParseSSMsg(buf, len); DispatchSS(ssMsg, param); // 走到JudgeFriendRes csMsg = ssMsg.msgReq; DispatchCS(csMsg, param); // 走到AddEnergyReq }
在JugdeFriendRes里,设置param
void JudgeFriendRes(ssMsg, param) { param = ssMsg.isFriend; }
设置这个参数后,DispatchCS用透传的数据,让流程继续回到AddEnergyReq。当第2次走到AddEnergyReq时,param != nullptr,直接判定是否是好友,接下来做该做的事情。
相关文章推荐
- 采用用同步编程的方式实现跨进程异步获取数据[二]-创建玩家账号和获取角色列表
- 采用用同步编程的方式实现跨进程异步获取数据
- dsp控制DM9000实现802.3数据收发第三篇,调试过程程序第三版;采用外部引脚中断方式获取中断,优化掉帧现象
- jQuery实现异步获取json数据的2种方式
- jQuery实现异步获取json数据的2种方式
- dsp控制DM9000实现802.3数据收发第三篇,调试过程程序第二版;接受部分可用,但是容易掉帧,采用的读取dm9000中断寄存器的方式获取数据
- 【java面试系列之网络编程】TCP和UDP的区别、TCP协议的三次握手和四次挥手、TCP协议的通信状态、网络编程时的同步、异步、阻塞、非阻塞、进程间的通信方式、TCP的流量控制和拥塞控制
- 传统方式实现AJAX异步获取数据,局部刷新
- 用 get 同步/异步 方式获取网络数据并输出
- 转发:Python通过Manager方式实现多个无关联进程共享数据
- 采用SQLServer 发布,订阅方式实现数据库同步遇到问题总结
- OPC的数据访问方法分别有同步访问、异步访问和订阅式数据采集方式------OPC(第一篇)
- 运用C#编程通过OPC方式实现PC机与西门子PLC通讯-同步通讯篇
- 网络编程_get_同步_获取网络数据
- Java异步I/O编程实现的两种方式:将来式和回调式
- spring jdbcTemplate实现中间库方式同步数据
- 不同数据源之间数据同步的几种实现方式
- 不同数据源之间数据同步的几种实现方式
- java 串口编程----监听方式获取串口数据
- 不同数据源之间数据同步的集中实现方式