三星galaxy a80玩崩坏三下载普通资源进去后能玩,但是退出到主界面(不在后台)后面,主界面卡

无论是聊天记录还是离线消息肯定都会在服务端存储备份,那么消息的安全性保护客户的隐私也至关重要。

因此所有的消息都必须要加密处理

在存储模块里,维护鼡户信息和关系链有两张基础表分别是im_user用户表和im_relation关系链表。

im_user表用于存放用户常规信息例如用户名密码等,结构比较简单

2)encrypt_key是随机生荿的密钥。当客户端登录时就会从数据库中获取该用户的所有的relation,存在内存中以便后续加密解密;

3)当客户端给某个好友发送消息时,取出内存中该关系的密钥加密后发送。同样当收到一条消息时,取出相应的密钥解密

客户端完整登录流程如下:

那为什么connector要先推送离线消息再更新session呢?

我们思考一下如果顺序倒过来会发生什么:

1)用户Alice登录服务器;

4)此时Bob发送了一条消息给Alice

如果离线消息还在推送嘚过程中,Bob发送了新消息给Alice服务器获取到Alice的session,就会立刻推送这时新消息就有可能夹在一堆离线消息当中推过去了,那这时Alice收到的消息就乱序了。

而我们必须保证离线消息的顺序在新消息之前

那么如果先推送离线消息,之后才更新session在离线消息推送的过程中,Alice的状态僦是“未上线”这时Bob新发送的消息只会入库im_offline,im_offline表中的数据被读完之后才会“上线”开始接受新消息这也就避免了乱序。

10.1 存储离线消息

當用户不在线时离线消息必然要存储在服务端,等待用户上线再推送理解了上一个小节后,离线消息的存储就非常容易了

增加一张離线消息表im_offline,表结构如下:

msg_type用于区分消息类型(chat,ack)content加密后的消息内容以byte数组的形式存储。

用户上线时按照条件to_user_id=用户id拉取记录即可

10.2 防止離线消息重复推送

我们思考一下多端登录的情况,Alice有两台设备同时登陆在这种并发的情况下,我们就需要某种机制来保证离线消息只被讀取一次

这里利用CAS机制来实现:

2)检查每条消息的has_read值是否为false,如果是则改为true。这是原子操作:

3)修改成功则推送失败则不推送。

相信到这里同学们已经可以自己动手搭建一个完整可用的IM服务端了。

[1] 更多IM代码实践(适合新手):

[2] IM群聊相关的技术文章:


[3] 有关IM架构设计的文章:


参考资料

 

随机推荐