开头
好友系统几乎是每个网络游戏都有的系统,以下用Erlang以例,分享一种好友系统的具体实现方式。
存储
可直接以user_id为key,存在ETS或序列化后存在Redis等公共安全的内存数据区域
存储在游戏公共区域的原因:
如果好友相关的信息存在角色(actor)的私有数据里面,在添加好友时,假设被添加方在线,就需要修改其已加载到内存中的数据;假设被添加方不在线,也需要修改其在数据库中的数据,过程麻烦且不易维护内存与DB的一致性,因此存储在公共可访问的内存里。
数据结构
%% 好友列表结构
-record(friend_list, {
user_id = 0,
list = [],
}).
%% 好友的数据结构
-record(friend_data, {
user_id = 0, %% 好友user_id
type = 0, %% 类型
data = #{} %% 扩展数据
}).
好友类型
-define(STRANGER,0).%% 陌生人
-define(GOOD, 1). %% 好友
-define(BLACK, 2). %% 黑名单
-define(APPLY, 3). %% 申请列表
每种类型都存在同一个列表中,取出来的时候再进行分类。
操作
1、好友列表
根据userid为key从内存中取出好友列表信息,进行好友列表/申请列表/黑名单的简单分类。
2、申请好友
根据自己和对方的user_id在公共内存数据中获得对应的好友列表,
进行以下检测:
- user_id是否合法(双方的user_id是否相等,格式非法等)
- 双方是否存在对方的黑名单中
- 双方是否存在对方的好友列表中
-
好友数量是否已到达上限
检测通过后,组成#friend_data{role_id=自己id, type=3}存入对方的好友列表,存公共内存数据表。
3、删除好友
根据自己和对方的user_id在公共内存数据中获得对应的好友列表,
进行以下检测:
-
双方是否存在对方的好友列表中
检测通过后,在双方列表互相删除对方好友,存公共内存数据。
4、同意/拒绝好友申请
根据自己和对方的user_id在公共内存数据中获得对应的好友列表,
进行下检测:
- 双方是否存在对方的申请列表中
- 双方是否存在对方的黑名单中
-
好友数量是否已到达上限
检测通过后,判断标志位是同意还是拒绝
#同意:组成#friend_data{role_id=双方id, type=1}以取代的方式存入各自的好友列表
#拒绝: 删除在自己在对方好友列表中的数据。
处理完成后,存公共内存数据表。
5、加入黑名单
根据自己和对方的user_id在公共内存数据中获得对应的好友列表,
进行下检测:
- user_id是否合法(双方的user_id是否相等,格式非法等)
- 对方是否在自己的黑名单中
-
黑名单是否已到上限
检测通过后,将对方加入自己的好友列表,type为2;如果自己在对方的好友列表,则删除。
存公共内存数据表。
6、取消黑名单
根据自己和对方的user_id在公共内存数据中获得对应的好友列表,
进行下检测1. 对方是否在自己的黑名单
检测通过后,自己的好友列表中移除对方。
7、查找好友
通过游戏昵称获取user_id, 判断对方与自己的关系,返回信息。
游戏服务端开发系列游戏服务端开发-好友系统
游戏服务端开发-排行榜
游戏服务端开发-邮件系统
游戏服务端开发-全局唯一ID
游戏服务端开发-AOI-九宫格法解析