现在的网游无论是手游还是端游,邮件系统几乎是必备的功能。游戏的邮件系统类似日常使用的邮件,可以是玩家发给玩家的邮件消息,也可以是系统发给玩家的消息,当然更重要的功能是附件(可以发放道具)和群发(可以用于定期活动奖励发放)。本文介绍的邮件系统基本是本人以往项目中设计的邮件系统的简化版。
首先,一封邮件存储的内容大致包括邮件ID,接收者,发送者,发送时间,过期时间,邮件类型,标题,内容,附件内容等。依据对邮件的索引缓存,我们又可以把他们拆分为邮件头和邮件体两部分。其中邮件头将作为索引缓存常驻内存,而邮件体则在玩家读取邮件或者领取附件时从数据库检索。MailID为主键,为(ReceiverID,Type) 建立索引,可以快速拉取发给某个人的所有邮件。注意,这里我为邮件分了类型,每一种类型都是单独处理的。
Head |
MailID ReceiverID SenderID SendTime ExpireTime Type |
Body |
Title Content ExtraType ExtraData |
把邮件划分了Head和Body,在玩家登录时,就可以全量拉取发送给该玩家的所有邮件头,而不用担心邮件数量过多占用太多内存。假设一个玩家有1000封邮件,假设一个Head占100B,那么该玩家邮件内存占用只有100k。
拉取时,已经过期的邮件可以立即删除,视情况自动领取附件或者直接删除。可以为每个玩家的邮件头缓存按照发送时间排序,按时间顺序增量推送给客户端,视客户端实现性能,可以只推数十个,翻页时由客户端主动请求,增量推送后面的邮件。当有新邮件时,可以通知客户端数量变化。客户端主动请求最新的邮件内容。
邮件有单独的类型,就可以为不同的业务功能提供不同的邮件服务。比如默认的邮件(带附件),用于支撑聊天的信息,用于特殊业务的奖励发放,用于特殊业务的常驻内容发送。推给客户端邮件系统的只有系统邮件和玩家邮件,其余邮件都在服务端处理,在登录或者某些特殊业务需求下拉取并处理。
Body中带有Extra信息,附件可以放到Extra内,对于特殊邮件,我们可以把特殊的内容放到Extra内,并根据类型做不同的处理。比如在我之前的项目中,就把发送给玩家的某些rpc,在玩家不在线时通过邮件发送,放到Extra内,这样在玩家下一次登录时,对该类邮件直接处理并删除,解析Extra内的协议,就像直接从另外一台服务器收到rpc消息一样。
以上都是点对点给玩家发送邮件。批量给玩家发送邮件有另外的服务,按照玩家列表依次给玩家发送邮件,因此并不需要邮件逻辑实现。另外还有一种邮件,发送给所有玩家的广播,例如读过就不在显示的系统消息,或者全服发放某个奖励,由于时间紧迫,当时尚未实现,可以做个思考。由于注册玩家可能非常多,给所有玩家都增加一条数据库记录是个很费的操作。因此可以考虑一个单独的广播邮件记录,内容除了ReceiverID,其他都一致,过期销毁。每个玩家维护一个已读广播邮件的列表(邮件ID和过期时间),玩家登录时活着在线定期拉取广播列表,剔除已读广播,剩下的根据类型做相应处理。
基本邮件内容到此就介绍完毕了,基本的思想很简单,但是真正实现起来还是会遇到一些坑。由于项目还在运营,不便讲太多细节,只能谈谈设计思路。有细节性的问题欢迎讨论。