首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >游戏服务器之多线程发送(上)

游戏服务器之多线程发送(上)

作者头像
李海彬
发布于 2018-03-22 08:37:25
发布于 2018-03-22 08:37:25
91400
代码可运行
举报
文章被收录于专栏:Golang语言社区Golang语言社区
运行总次数:0
代码可运行

本文讨论的游戏架构设计中,分为两进程(逻辑服务器进程和数据服务器进程),其中逻辑服务器进程包含多个逻辑网关,单个逻辑网关中含4类线程,发送线程是其中一种并在一个逻辑网关中存在多个,用来处理发送业务。

设计上:

(1)每个玩家有对应的发送线程(N:1,根据发送线程数量哈希取余),发送时需要把数据包提交到该线程的发送添加队列里。 (2)每个玩家有个对应的网关指针 (3)分配发送线程时,会根据网关用户索引(这里的用户索引是会话索引,是会话列表中该会话的下标),获取逻辑网关上的会话列表中的会话。 (4)网关用户索引取余该逻辑网关上的发送线程数,从发送线程列表获取发送线程,并把发送包提交到该发送线程的消息队列。 (5)每个发送线程有个单独的数据包内存池。逻辑线程和每个发送线程交换数据时,每个发送线程有个单独的互斥量。数据包内存池的分配和回收都需要加锁(因为逻辑线程和发送线程之间的数据包内存池管理需要互斥)。

1、申请发送数据包

申请发送数据包,需要从逻辑网关的指定发送线程的内存池里获取。

在逻辑网关里分配发送数据包,根据该用户的网关会话索引就可以获取该玩家的会话,再哈希获取发送线程数组中的发送线程。需要设置该包的发送线程、用户索引、验证码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline CGateSendPacket& allocSendPacket() { return m_pGate->AllocSendPacket(m_nGateUserIndex); }  
 
CGateSendPacket& ExecSockDataMgr::AllocSendPacket(const int nUserIndex)//nUserIndex 是网关里的用户的索引 
{  
    PRUNGATEUSERSESSION pSession = m_SessionList[nUserIndex];//每个逻辑网关有一个会话列表,每个玩家相对应的会有一个用户索引 
    assert(pSession != NULL);  
    PEXECDATASENDTHREAD pSendThread = &m_SendThreads[nUserIndex % m_nSendThreadCount];//哈希发送线程(发送线程的个数是配置的,目前单逻辑网关有2个发送线程,因为游戏服务器发送的数据比接受的数据要多些) 
    CGateSendPacket *pPacket = pSendThread->pSendPacketPool->allocPacket();  
    pPacket->setSendInfo(pSendThread, nUserIndex, pSession->nVerifyIdx);//设置发送线程指针 
 return *pPacket;  
}  

数据发送线程中的数据缓存结构

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct structExecDataSendThread  
{  
    ...  
 int nThreadIdx; //线程id 
    CRITICAL_SECTION SendQueueLock;//互斥锁(临界区) 
    CBList<CGateSendPacket*> *pSendAppendList;//发送添加列表 
    CBList<CGateSendPacket*> *pSendProcList;//发送处理列表 
    CGateSendPacketPool *pSendPacketPool;//发送数据包池 
}EXECDATASENDTHREAD, *PEXECDATASENDTHREAD;  

2、逻辑线程提交发送包

在提交后会把该数据包提交到该发送线程的数据包添加队列里。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CGateSendPacket &pack = ((CPlayer*)viewList->pEntity)->allocSendPacket();  
pack.writeCmd(sysBattle, sStartRun);  
pack << data;//写入字节流 
pack.flush();  
//提交网络数据包到发送队列 
inline void flush()  
{  
 if (m_pSendThread)  
    {  
        EnterCriticalSection( &m_pSendThread->SendQueueLock );  
        m_pSendThread->pSendAppendList->add(this);//添加到该线程的发送添加队列 
        LeaveCriticalSection( &m_pSendThread->SendQueueLock );  
        m_pSendThread = NULL;//置空避免重复提交 
    }  
}  
3、发送数据线程例程
把发送队列的数据拷贝到发送缓冲区。
发送发送缓冲区中的数据。
发送时需要验证发送包的验证码(nVerifyIdx)跟会话的验证码是否是一样的(发送的验证码(主要适用于服务器之间的连接的安全验证,对于客户端的连接可考虑去掉)[cpp] view plain copy 
void *ExecSockDataMgr::SendDataProcessRoutine(PEXECDATASENDTHREAD pRunThread)  
{  
    TICKCOUNT dwProcStartTick;  
    ExecSockDataMgr *pRunData;  
 int nLockSendBufQLockFail = 0;  
    pRunData = pRunThread->pRunData;  
 while ( !pRunData->m_boStoping )  
    {  
        dwProcStartTick = _getTickCount();  
 if ( pRunData->CopyWaitSendBuffers( pRunThread, TRUE ) )//交换发送队列和添加队列,拷贝会话的发送队列的数据到会话的发送缓冲区 
        nLockSendBufQLockFail = 0;  
 else nLockSendBufQLockFail++;  
        pRunData->CheckSendSessionBuffers( pRunThread );//发送会话的的发送缓冲区的数据 
 //循环小于指定时间则休眠一次(16ms),避免频繁io发送(发送可缓存在队列和发送缓存中) 
        pRunThread->dwProcTick = _getTickCount() - dwProcStartTick;  
 
 if ( pRunThread->dwProcTick < 16 )  
        {  
            dwProcStartTick = _getTickCount();  
            moon::OS::osSleep( 1 );  
        }  
    }  
    ExitThread( 0 );  
}  

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
游戏服务器之多线程发送(下)
5、发送缓冲区数据 检查可发送该线程的相关联的所有会话上的发送缓冲区的数据,检查完后,发送会话上的发送缓冲区的数据。 VOID ExecSockDataMgr::CheckSendSessionBuffers(PEXECDATASENDTHREAD pSendThread) { int nErr, nRemainSize; char *pBuffer; PRUNGATEUSERSESSION *pSessionList = m_SessionList; PRUNGAT
李海彬
2018/03/22
6580
游戏服务器之多线程发送(中)
4、拷贝数据到会话的发送缓冲区 交换发送队列和添加队列,拷贝会话的发送队列的数据到会话的发送缓冲区 BOOL ExecSockDataMgr::CopyWaitSendBuffers(PEXECDATASENDTHREAD pSendThread, BOOL boForceCopy) { CGateSendPacket *pSendPacket, **ppPacketList; CBList<CGateSendPacket*> *pBufferList; PRUNGA
李海彬
2018/03/22
7570
9 百万用户级游戏服务器架构设计
所谓服务器结构,也就是如何将服务器各部分合理地安排,以实现最初的功能需求。所以,结构本无所谓正确与错误;当然,优秀的结构更有助于系统的搭建,对系统的可扩展性及可维护性也有更大的帮助。
范蠡
2018/07/25
4.2K0
9 百万用户级游戏服务器架构设计
教你从头写游戏服务器框架
大概已经有差不多一年没写技术文章了,原因是今年投入了一些具体游戏项目的开发。这些新的游戏项目,比较接近独立游戏的开发方式。我觉得公司的“祖传”服务器框架技术不太适合,所以从头写了一个游戏服务器端的框架,以便获得更好的开发效率和灵活性。现在项目将近上线,有时间就想总结一下,这样一个游戏服务器框架的设计和实现过程。
韩伟
2019/01/30
4.3K1
教你从头写游戏服务器框架
Golang语言社区--游戏服务器端开发的一些建议(转载)
大家好,我是Golang语言社区(www.golang.ltd)主编彬哥,本篇给大家转载一篇关于游戏服务器开发的文章。
李海彬
2018/03/18
2.9K0
Golang语言社区--游戏服务器端开发的一些建议(转载)
游戏服务器之逻辑服务器的资源分布图
线程类型分成三大类:主线程、网络线程、业务线程。 一、主线程 1、程序主线程(线程1) 读取服务器配置,读取逻辑数据配置,启动账号管理器、日志管理器,启动逻辑引擎(启动账号管理器、启动db管理器(连接数据服务器进程)、启动网关、启动日志管理器、初始化游戏命令)。 二、网络线程 1、逻辑网关(线程2-4和n) 框架是使用多网关结构的逻辑进程。每启动一个逻辑网关,就会启动对应的网络连接监听、接收、发送、和数据缓存处理线程: 网络线程类型包括: (1)网络连接监听线程 (2)网络数据接收线程 (3)数据缓冲处理
李海彬
2018/03/22
9940
揭秘游戏服务器,不看后悔!!!
《摩尔庄园》前段时间上线,  持续超出市场预期,相信也有不错的收益。游戏好玩,所有玩家看到了前端,但是做一款游戏,离不开后台游戏服务器的支持,服务器都要做什么,服务器的架构是什么,需要哪些技术,一系列的问题有没有思考过?下面讲下作为做服务器开发中需要做的事。
香菜聊游戏
2021/06/15
1.7K0
1 游戏服务器开发的基本体系与服务器端开发的一些建议
近年来,我身边的朋友有很多都从web转向了游戏开发。他们以前都没有做过游戏服务器开发,更谈不上什么经验,而从网上找的例子或游戏方面的知识,又是那么的少,那么的零散。当他们进入游戏公司时,显得一脸茫然。如果是大公司还好点,起码有人带带,能学点经验,但是有些人是直接进入了小公司,甚至这些小公司只有他一个后台。他们一肩扛起了公司的游戏后端的研发,也扛起了公司的成败。他们也非常尽力,他们也想把游戏的后端做好。可是就是因为没什么经验,刚开始时以为做游戏服务器和做web差不多,但是经过一段时间之后,才发现代码太多,太乱了,一看代码都想重构,都是踩着坑往前走。
范蠡
2018/07/25
5.4K0
1 游戏服务器开发的基本体系与服务器端开发的一些建议
12 经典游戏服务器端架构概述
现代电子游戏,基本上都会使用一定的网络功能。从验证正版,到多人交互等等,都需要架设一些专用的服务器,以及编写在服务器上的程序。因此,游戏服务器端软件的架构,本质上也是游戏服务器这个特定领域的软件架构。 软件架构的分析,可以通过不同的层面入手。比较经典的软件架构描述,包含了以下几种架构: 1.运行时架构——这种架构关心如何解决运行效率问题,通常以程序进程图、数据流图为表达方式。在大多数开发团队的架构设计文档中,都会包含运行时架构,说明这是一种非常重要的设计方面。这种架构也会显著的影响软件代码的开发效率和部署效率。本文主要讨论的是这种架构。 2.逻辑架构——这种架构关心软件代码之间的关系,主要目的是为了提高软件应对需求变更的便利性。人们往往会以类图、模块图来表达这种架构。这种架构设计在需要长期运营和重用性高的项目中,有至关重要的作用。因为软件的可扩展性和可重用度基本是由这个方面的设计决定的。特别是在游戏领域,需求变更的频繁程度,在多个互联网产业领域里可以说是最高的。本文会涉及一部分这种架构的内容,但不是本文的讨论重点。 3.物理架构——关心软件如何部署,以机房、服务器、网络设备为主要描述对象。 4.数据架构——关心软件涉及的数据结构的设计,对于数据分析挖掘,多系统协作有较大的意义。 5.开发架构——关心软件开发库之间的关系,以及版本管理、开发工具、编译构建的设计,主要为了提高多人协作开发,以及复杂软件库引用的开发效率。现在流行的集成构建系统就是一种开发架构的理论。
范蠡
2018/07/25
8.1K1
12 经典游戏服务器端架构概述
再谈游戏服务器架构
一、服务器划分原则 在现有的网络游戏服务器端架构中,多是以功能和场景来划分服务器结构的。负载均衡和集群暂且不在本文中讨论(bigworld、atlas)。服务器划分可以基于以下原则: 分离游戏中占用系统资源(cpu,内存,IO等)较多的功能,独立成服务器。 以多线程或多进程的编程方式适应多核处理器。 在同一个服务器架构下,应尽可能的复用某些服务器(进程级别的复用,比如场景服务器)。 运行时玩家数据的保存、修改及数据流向应该是设计的焦点,它同时也决定了服务器应该如何划分。 服务器的划分应该适度,在保
李海彬
2018/03/22
4.6K0
再谈游戏服务器架构
4 关于游戏服务端架构的整理
一个大型的网落游戏服务器应该包含几个模块:网络通讯,业务逻辑,数据存储,守护监控(不是必须)。其中业务逻辑可能根据具体需要,又划分为好几个子模块。
范蠡
2018/07/25
3K0
4 关于游戏服务端架构的整理
游戏服务器之多进程架构通信
游戏服务器有时需要分多个进程来处理各种负载。多个进程之间的连接处理就相对复杂了。 1、服务器进程类型 (1)登陆服务器 创建账号,检验角色账号,选择和获取并返回网关信息。 (2)网关服务器 创建角色,转发消息。会有网关角色,和相关的屏信息,用于广播。 (3)场景服务器 处理场景(分线或不分线的)、副本的游戏逻辑。 (4)社会关系服务器 处理社交相关的全区的逻辑。 (5)数据库服务 存取数据。 (6)中心服务器 处理内部服务器之间的消息转发,和某些转发流程控制。 (7)其他服务器 还有些日志服务器、连接php
李海彬
2018/03/22
2K0
游戏服务器之多进程架构通信
11 一种高性能网络游戏服务器架构设计
网络游戏的结构分为客户端与服务器端,客户端采用2D绘制引擎或者3D绘制引擎绘制游戏世界的实时画面,服务器端则负责响应所有客户端的连接请求和游戏逻辑处理,并控制所有客户端的游戏画面绘制。客户端与服务器通过网络数据包交互完成每一步游戏逻辑,由于游戏逻辑是由服务器负责处理的,要保证面对海量用户登录时,游戏具有良好的流畅性和用户体验,优秀的服务器架构起到了关键的作用。
范蠡
2018/07/25
6K0
11 一种高性能网络游戏服务器架构设计
教你从头写游戏服务器框架(3)
使用异步非阻塞编程,确实能获得很好的性能。但是在代码上,确非常不直观。因为任何一个可能阻塞的操作,都必须要要通过“回调”函数来链接。比如一个玩家登录,你需要先读数据库,然后读一个远程缓冲服务器(如 redis),然后返回登录结果:用户名、等级……在这个过程里,有两个可能阻塞的操作,你就必须把这个登录的程序,分成三个函数来编写:一个是收到客户端数据包的回调,第二个是读取数据库后的回调,第三个是读取缓冲服务器后的回调。
韩伟
2019/05/08
2.9K3
教你从头写游戏服务器框架(3)
游戏服务器架构概要
方案:切分xysvr,让多个scene分别服务于一些用户,world负责拉取数据。并协调控制多scene。
Zoctopus
2018/08/10
2K0
游戏服务器架构概要
游戏服务器架构演化史pdf_分布式游戏服务器
类型1:卡牌、跑酷等弱交互服务端 卡牌跑酷类因为交互弱,玩家和玩家之间不需要实时面对面PK,打一下对方的离线数据,计算下排行榜,买卖下道具即可,所以实现往往使用简单的 HTTP服务器:
全栈程序员站长
2022/11/01
1.2K0
游戏服务器架构演化史pdf_分布式游戏服务器
Java在游戏服务器开发中应用【面试+提高】
Java在游戏服务器开发中的应用 随着游戏市场的兴起,特别是网页游戏、手机游戏的崛起,对游戏开发技术的需求越来越多。网络游戏开发是一个庞大的体系,总体来说是客户端与服务器端。客户端是玩家接触的游戏图像显示端,服务器是处理游戏运行中的各种数据,由于一台服务器要支持众多玩家的请求,所以服务器的性能高低决定了同一个游戏的用户数量。 我们公司选择使用Java做服务器开发语言,主要原因是:1.Java是跨平台的,方便部署;2.Java是安全的高级语言,可以提高开发效率;3.Java是面向对象的,代码可以重用;4.Ja
Java帮帮
2018/03/12
2.1K0
Java在游戏服务器开发中应用【面试+提高】
Java之多线程优化与CPU、I/O之间的深入理解
在高并发的场景之下,Java经常使用到的技术就是多线程。而多线程的使用,到底是否真的能够有效地提高服务的性能和效率,就必须拿捏得当,从计算机操作系统,到服务代码,到应用上线之后的监测。得谨小慎微的行走~
23号杂货铺
2019/09/26
4.3K0
经典游戏服务器端架构概述 (1)
本文介绍了多进程模型在游戏服务器端开发中的实践,重点讲解了如何利用多进程模型实现游戏服务器的负载均衡、服务状态管理、无缝扩展和容灾备份等方面的技术和实现方式。
韩伟
2016/12/02
7.4K0
经典游戏服务器端架构概述 (1)
[自己做个游戏服务器二] 游戏服务器的基石-Netty全解析
Netty的大名我想做java 的基本都知道,因为他实在太出名了,现在很多著名的软件都是使用netty作为通讯基础,今天就聊聊Netty,希望能讲清楚,如果懒得看理论,可以直接拉到后面看Hello world。把代码抄下来,运行一下看看。
香菜聊游戏
2021/10/19
2K0
[自己做个游戏服务器二] 游戏服务器的基石-Netty全解析
相关推荐
游戏服务器之多线程发送(下)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档