GS与MS之间通信
注意GS与MS是两个线程,现在是每个map一个线程,他们之间是内部协议进行通信的,那既然是两个线程那如何通信呢,看了net进程通信这个就比较简单了
举个例子
m_pMap->Gs2MsData(gs2ms_add_player, m_nChannelId, (void*)&rActorEx, sizeof(rActorEx));//发送玩家上线包
void Map::Gs2MsData(int cmd, int channel_id, void* data, int len)
{
MapPkt pkt;
pkt.channelId = channel_id;
pkt.data = m_memPool.popPkt(len);注意这个m_memPool是线程安全的队列,内部是boost无锁队列实现的
memcpy(pkt.data, data, len);//不同线程需要内存拷贝,不可能使用同一块地址
pkt.len = len;
pkt.cmd = cmd; PushPkt(pkt);
} void ThrTransData::PushPkt(MapPkt Pkt)
{
for (;;)
{
if(m_gs2msPkts2.push(Pkt))//将包放入boost无锁队列中
break;
cxx11::this_thread::interruptible_wait();
}
}
那看看MS这边是如何取的
在share初始化的时候开启了一个线程,这个线程可以说整个map的数据都是这里面处理的
bool ThrTransData::GetDataFromQueue(MapPkt* pPkt)
{
if(m_gs2msPkts2.empty())
return false;
{
MapPkt tmpPkt;
if(m_gs2msPkts2.pop(tmpPkt))//从GS到MS这端的无锁队列中取包
{
*pPkt = tmpPkt;
return true;
}
return false;
}
return true;
}
if(GetDataFromQueue(&Pkt))
{
ProcessPkt(Pkt);//解析包调用相应函数
m_memPool.pushPkt(Pkt.data, Pkt.len);//将内存池归还 nCount++;
if(nCount > )
{
nCount = ;
m_spTimerFactory->driveTimer();
}
continue;
}
//至此从GS到MS这边的包就是这样处理的 那从MS到GS的包
从Map需要发到GS的包也不多,还有一种通过GS转到map的
SendCmd2Gs(ms2gs_prop_mgr, nChannelID, pData, nLen);
void SendCmd2Gs(int nCmd, int nChannelId, void* pData, int nLen)
{
MapPkt Pkt;
Pkt.cmd = nCmd;
Pkt.channelId = nChannelId;
char* pszNewBuffer = new char[nLen];//这个是自己new的,发送到MS是从内存池中获取的
memcpy(pszNewBuffer, pData, nLen);
Pkt.data = pszNewBuffer;
Pkt.len = nLen;
PushData2GS(Pkt);
}; void PushData2GS(const MapPkt& Pkt)
{
while()
{
if(m_quePkts2Gs.push(Pkt))//从MS发送到GS的队列
}
}
那GS是如何去的呢
void Share::ProcMapSendData()//这个是GS驱动的
{
if(!itMap.second->RecvData(Pkt))//从无锁队列中取包
break;
if(Pkt.cmd == ms2gs_转client_cmd)//针对包进行处理
{
OnTurnToClient(Pkt.channelId, Pkt.data, Pkt.len);
}
}
//开来发包都是双向的,需要两个队列,这个在net那边也是的
//其次就是需要额外的内存放到队列中,因为不可能去操作同一块内存的,要么自己new,要么从内存池中分配
//MS与GS之间通过MapPkt进行通信,对于客户端和服务器通过protocol通信,通常是自己定义一块buf,然后打包到BUF中,net那块也是在内存池中分配一块然后存储这个buf,因为这个buf也是公用的
//刚开始不懂程序就是这些内存问题没有搞清楚

GS与MS之间通信的更多相关文章

  1. 【转】wpa_supplicant与wpa_cli之间通信过程

    [转]wpa_supplicant与wpa_cli之间通信过程 转自:http://blog.chinaunix.net/uid-26585427-id-4051479.html wpa_suppli ...

  2. 【linux】mkfifo 命令创建命名管道实现进程之间通信

    mkfifo 命令 mkfifo命令创建一个FIFO特殊文件,是一个命名管道(可以用来做进程之间通信的桥梁) 管道也是一种文件,一般是linux中的一个页大小,4k,管道数据一旦被读取就没了.(管道大 ...

  3. 客户端与服务器之间通信收不到信息——readLine()

    写服务器端和客户端之间通信,结果一直读取不到信息,在https://blog.csdn.net/yiluxiangqian7715/article/details/50173573 上找到了原因:使用 ...

  4. 【Vue课堂】Vue.js 父子组件之间通信的十种方式

    这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...

  5. VLAN之间通信-三层交换

    实验目的 VLAN之间通信-三层交换 掌握配置VLANIF接口的方法 理解数据包跨VLAN路由的原理 掌握测试多层交换网络连通性的方法 实验原理 三层交换机在原有二层交换机的基础之上增加了路由功能,同 ...

  6. 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信

    官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...

  7. iframe之间通信问题及iframe自适应高度问题

    下面本人来谈谈iframe之间通信问题及iframe自适应高度问题. 1. iframe通信 分为:同域通信 和 跨域通信.所谓同域通信是指 http://localhost/demo/iframe/ ...

  8. (六)ROS话题---节点之间通信的方式

    1. 理解 ROS 话题: (Ctrl+Alt+T 打开一个新终端) 运行下面的命令: $ roscore (Ctrl+Alt+T 打开一个新终端) $ rosrun turtlesim turtle ...

  9. vue组件之间通信传值

    原文链接:https://blog.csdn.net/lander_xiong/article/details/79018737 我认为这位博主的这篇文章写的非常详细,通俗易懂, 我们这次的vue项目 ...

随机推荐

  1. PHP登陆提示信息框代码

    出错的提示框 echo "<Script Language='Javascript'>";   echo "alert('提示:用户名密码错误,请重新输入!' ...

  2. 联想台式机启天m4350 启用intel vt-x

    在vmware workstations10 64位上安装windows server 2012操作系统时,出现例如以下错误: 已将该虚拟机配置为使用 64 位客户机操作系统.可是,无法运行 64 位 ...

  3. shoppingCart.js

    ylbtech-JavaScript-util: shoppingCart.js 购物车脚本 1.A,JS-效果图返回顶部   1.B,JS-Source Code(源代码)返回顶部 1.B.1,m. ...

  4. JSONUtil.bean2Json()报Property 'key' of class has no read method. SKIPPED的问题处理

    错误警告信息描述: net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:) Property 'handler' of class ...

  5. http://bbs.51cto.com/thread-1070029-1-1.html

    http://bbs.51cto.com/thread-1070029-1-1.html

  6. 新人补钙系列教程之:Molehill底层API中最重要的Context3D

    Context3D,是一个三维空间的处理环境,负责创建并处理三维对象的各个要素如顶点.片段.透视等等,并将处理的结果使用AGAL(Adobe图形汇编语言)上传给显卡进行运算,运算结果最终被回传给CPU ...

  7. scrapy爬虫 函数间传值简易教程

    2017-03-27 有的时候我们爬取数据的时候需要在多个页面之间跳转,爬取完所有页面的数据的时候才能把所有数据一起存到数据库,这个时候我们就需要把某个函数内爬取的数据传到下一个函数当中.有人可能会说 ...

  8. Node.js 使用http客户端向网站请求数据并保存

    app.js代码: // 内置http模块,提供了http服务器和客户端功能 var http=require("http"); // 内置文件处理模块 var fs=requir ...

  9. Windows网页上碰到无法完全显示的图片怎么办

    如图所示,下一幅图片只能显示一半. 我们选中并在新标签中打开 一般即可正常显示,如果还不行,留意地址栏,这就是这个图片的真实地址,我们完全可以用迅雷直接把这幅图片下载下来. 我们甚至可以猜测,去掉后缀 ...

  10. iOS 设置导航栏 返回按钮文字隐藏

    //隐藏返回按钮文字 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) f ...