开发者社区> 问答> 正文

仿微信IM软件的客户端数据库设计

软件主要有两个界面:会话界面和联系人界面,会话包括两人会话和群组会话。
界面里的列表元素分别对应两个实体类:Room(代表一个会话)和User。而会话里的消息对应实体类Message。
当涉及持久化以供离线时使用时,该如何设计数据库呢?
目前的想法是客户端登录的不同用户对应不同数据库(比如用户labmem对应labmem.db),所有Room放在表roomtable中,然后每个会话对应的成员列表和消息列表该如何存放呢?
有个想法是把某个会话相应的成员表表名和消息表表名作为roomtable的两列进行存放。
但这样用RecyclerView显示时将十分麻烦,比如会话界面,需要先查询roomtable,再根据结果一个个查询相应的成员表和消息表。
该怎样设计数据库的表比较好呢?
如果知道有比较好的demo的话也请提供链接,谢谢。

补充:
上面说的可能有些不清楚。我拿微信做例子说明:当网络联接不可用时,微信依然是可以查看会话列表、会话的所有聊天记录(只要你没把这个会话删除)和群组会话的所有成员的,还有通讯录列表。
我就想知道实现这样的设计需要怎样设计数据库的表,以方便地将所有信息像微信那样,离线时也可以显示出来。

展开
收起
a123456678 2016-07-04 11:19:25 4591 0
1 条回答
写回答
取消 提交回答
  • 最近我也在写一款开源的IM系统,就说说一些心得吧。

    首先,你需要一个用户资料服务器,用来存储用户信息,用户名,以及用户ID等,这一块的数据库可以用一个单独的服务器来托管。
    其次,你还需要一个IM服务器,IM服务器用来接受客户端的长连接,当客户端登陆IM服务器时,需要 携带着ID发送连接命令,IM服务器用一个HashMap来保存,另外还需要一个HashMap来保存来进行用户状态的一些逻辑。
    对于IM这种高并发的项目,建议用Redis这种内存数据库,我的做法是,一个Redis库来保存用户的待发送消息,用ID做Key,待发送的消息编号列表做Value;另一个Redis库来储存消息实体,自增ID做Key,序列化后的消息做Value。
    其次是保证消息的不丢失,我现在的方案是,每个客户端发送的每条消息都有一个uid,格式化是客户端发送消息时的时间戳-客户端ID,这样只要客户端没收到服务端的ACK信号(应用层),就一直重发这条消息,但是uid不变,服务端检查uid,如果和数据库里面的重复,就把消息丢弃,再发送一个ACK信号,这样就可以保证客户端发出的消息能到达服务端。
    服务器每次接收到新的消息时,都查看收信者,假设收信者ID是5,那我们就把5所有待接收的消息全发送给5。
    具体的可以看一下NoNOIM

    2019-07-17 19:50:33
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
微信广告引擎与播放节奏算法实践 立即下载
微信H5视频播放器在海量业务下的实践 立即下载
微信高效运维之路 立即下载