栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Netty游戏服务器消息分发技巧(channelRead处处理)

Java 更新时间:发布时间: 百科书网 趣学号

阅读pomelo项目的启发,其实游戏都是有一个模块号的,可以根据模块号做好具体的分发,业务代码写的时候,就可以保证完全按照单线程的逻辑写即可。在zfoo中,其实就是根据玩家请求过来的packet,就可以得到module的name,知道这个请求属于哪个模块。那这个玩家的请求到底投递到哪个线程呢?

1)以斗地主为例子:

        1.登录前的模块 "auth":

                这个是:在登录账号前,还没有uid时。也就是:拿着account进行登录,此时是直接取

                        account这个账号作为执行线程。

                        TaskBus.addTask(account, ()=>{  这写操作db的逻辑 } ),这样子保证玩家不管怎么登录,都是串行处理,避免一下子同一个账号搞进来2个连接。

        总结:先采用默认的sid做路由进入到handler内,执行业务逻辑时,根据accountId做路由。

        2.玩家相关的模块 "player":

                这个模块处理的都是登录过后只处理个人数据的业务,如:每日登录、引导。

                此时都在路由层处理好,

                总结:根据uid进行映射到指定的线程。

        3.匹配相关的模块 "match":

                 匹配一般只有一个线程,这样子处理就可以完全无锁化,也无需使用加锁。

                但是,匹配成功后要创建房间,此时要先生成房间号,生成房间号可以用内存原子变量,一旦生成房间号后,就可以根据房间号进行操作,往房间管理里面添加room等可以到房间线程执行。

                总结:单独独立出来一个匹配线程进行逻辑处理。之后的临界情况:确定下来roomId后就到roomId指定的线程执行。

        4.房间相关的模块 "room":

                此时都是房间内的逻辑,从玩家Session上要绑定好房间roomId,此时所有的请求都路由到房间线程即可。 也可以将房间线程单独开辟一个房间线程池,这样子就完全没有db操作,会更快一点。 结算之后,再把结果放到玩家线程中进行db相关的处理:

        TaskBus.addTask(uid, ()=>{  这写操作db的逻辑 } ),这样子保证。

        总结:房间内逻辑用roomId做路由,结算等涉及多人信息的,采用uid做路由,在里面修改个人数据库。

2)好处:

        无需大部分情况下,无需进行手动hash映射(登录前、房间内结算每个人信息相对特殊)

3)要写好单进程多线程类的游戏逻辑

        大部分都是分区分服类的游戏,因为方便游戏运营。

        一个12c32g内存的游戏服务器,那已经可以支撑很多人了,其实jvm堆内存也要求不可超过32G,JAVA堆大小不要超过32GB!!!_占小狼的技术博客_51CTO博客

----------------------------------------思考--------------------------------

经过上面的分析可以看出来,很多业务中都会存在一些临界情况:

        如:登录前不知玩家uid,登录后确定下来玩家uid,但是分配uid和初始化uid对应的玩家数据此时是在登录前的这个线程中。那么后续的存储操作可以提交的uid的线程中。

      还有:处理创建房间的handler,此时还没roomId,那么分配roomId和存储这个new出来的Room这个操作也是在默认在创建房间的线程中。那其实后续的操作可以提交到房间线程中。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/1032873.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号