golang 手游框架设计 - 本人浅陋的见解, 求达人指正

如有错误的地方,请同仁指正,非常感谢

第一种方式:

3个进程

Login: 登陆服(同时用于聊天系统)  socket长连接

Game: 游戏服(游戏逻辑处理)  http短连接

Mysql: 数据库回写 socket

 

客户端socket连接login,保持长连接,验证成功后,game服以http方式请求数据

game服向loginhttp方式验证该客户端是否已经正常登陆, 1: 没有登录则,game返回数据给客户,没有登录状态. 2: 已经登陆,game返回所需数据给客户端.

game将修改后的数据以sql语句形式发送给mysql,同时记录当前sql到文件中用于备查.

 

使用单独login服的好处在于 客户端可以一直保持连接,并且login服逻辑处理少. 服务器压力小.同时在game服有问题需要闪断时,还能继续保持玩家登陆状态,在紧急更新game服后,客户端不需要重新连接登陆游戏. 并且因为login较少的逻辑处理, 各个socket共存连接能力相应变强.可以提高同时在线玩家数. 使用socket连接,便于服务端主动向客户端发送聊天,公告等信息.  game服连接方式不同,主要是因为两个进程间功能不同导致.

 

game服使用http方式,http处理能力相较于socket更好,使用更方便,基本不需要去考虑网络连接的状态问题.客户端需要什么数据,可以直接Get请求. 对于每次请求数据,都是单独一个go, http并发处理也会更好.

 

具体实现:

login只读取玩家的Account信息用于验证.不生成新sql数据. 如果新用户登陆,则生成一份临时数据用于表示新用户登陆成功.返回给客户端一个uid.作为客户端登陆的标记. 客户端向game服请求数据时,再由game生成sql数据,同时get方式通知login服临时数据为永久数据. sql语句通知mysql服回写数据.

客户端每次向game请求数据都需要带上参数uid, game服使用uidlogin服通过http方式验证客户端是否已经登陆成功. 1:没有登录则提醒登陆 2.已经登陆,则处理逻辑数据  (这里有个问题,gamelogin直接的验证会非常频繁)

 

game的数据处理,则使用内存共享方式.

game服启动时将mysql数据库中的数据全部读取到内存中. 结构如下:

type UserData struct{//单个玩家的结构数据

         Account Account //单个玩家的账号信息,元宝,铜钱等属性

         Bag []Bag //单个玩家的背包物品数据. 多个物品

         Friend []Friend //单个玩家的好友 多个好友

         ....

         mu    sync.RWMutex //单个玩家的数据锁

}

UserDatas = make(map[int32]UserData)  //全服所有玩家数据

 

type Shop struct{ //商店表 配置表

         ....

}

ShopInfo = make(map[int32] Shop) //商店的配置表数据

 

......

说明a: 玩家的信息,统一放在UserData,多条数据使用slice结构,尽量减少"对象"数量.

不能统一的数据则单独一个结构.

 

game服在游戏过程中,只要数据变化则生成优化后的sql语句,通知mysql服回写到数据库

 

mysql只负责接收sql语句, 并写入到数据库,记录下当前写成功的sql语句第几条.用于数据出错时. 对比sql文件,已经写到哪一条语句.便于恢复数据库. 如果一旦数据回写错误,则停止接下去的语句回写, 需要记录下后续语句的数量即可, 并马上通知dba管理员.

 

说明b: 如果一个玩家操作需要影响到其它玩家,则由game服请求login,login服主动通知客户端数据.免去了客户端定时请求某些操作的麻烦.

例如: A玩家在地图上移动,需要通知周边其它玩家,A玩家新的坐标点. 此时由game服请求login,login服通知在线玩家A的新数据.

 

第二种方式:

http连接.

game: http连接

mysql:数据回写处理.

 

A玩家向game请求登陆,game验证成功后,记录A玩家登陆成功,并返回给客户端uid.则此后3分钟都认为该uid的玩家处于登陆状态. A客户端每次请求数据都更新A玩家的最后时间.

其中uid为加密后的数据. 每次重新验证则生成不同的uid.

http的弊端: 服务器不能实时通知客户端信息.

游戏中建立玩家数据更新标志位. A玩家定时2-5秒请求公告标志位,发现公告标志位是新的,则读取.

A玩家移动,需要通知其它周边玩家, 则向其它玩家的移动处理队列中添加新数据,并更新通知标志位, B玩家每1-2秒请求检查标志位状态,有新数据则获取.

 

 

以上两种方式,其中数据传输该加密的方式则需要加密.

本人新手,求达人指正


本文来自:开源中国博客

感谢作者:984195889

查看原文:golang 手游框架设计 - 本人浅陋的见解, 求达人指正

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。