消息系统设计

目录

存储消息

发件箱

收件箱

消息结构

消息类型

拓展

校验内容

拉取消息


PS:

最近在做一些消息相关的内容,对消息做了一下总结,包括发送、接收、存储等,记录一下,欢迎大家交流拓展。

存储消息

redis临时存储,数据结构zset

kafka异步持久化到db,由于消息表数据量比较大,msg表按照createdTime分区。

发件箱

sendBox  redis zset实现。

zadd nx,key:固定前缀+senderId,score:msgId,member:clientId

发件箱的作用?

  1. 发件箱根据雪花算法生成统一的msgId。
  2. 主要作用是为了防止同一条消息重复发送。
    1. 客户端发送消息时,有clientId,防止弱网导致客户端显示发送失败,但实际上服务端成功处理的情况。
    2. 相同clientId的消息不会发到receiver的收件箱。

最大消息限制

最多保留100条消息,zremrangebyrank

收件箱

inBox:redis zset实现。

zadd,key:固定前缀+receiverId,score:msgId,member:msg

发送消息最终是添加到receiver的收件箱,这样拉取消息时,每个人拉取自己的收件箱即可。

最大消息限制

最多保留最近一个月的消息,zremrangbyscore

消息结构

消息类型

发消息设计的数据结构需要支持文本、语音、图片、视频等格式。

可以统一定义一个字段为msgType,然后区分不同类型,定义枚举,每一种类型对应一种结构。

如msgType为“text”,对应结构为:

“text": {

    "value": "发送文本消息"

}

如msgType为”image“,对应结构为:

”image": {

    "url": "https://xxxxxxxx",

    "width": 80,

    "height": 80

}

其他类型同理。

最终类似于这种:

type Message struct {

    Id int64 `json:"id"`

    ClientId string `json:"clientID"`

    MsgType string `json:"msgType"`

    Text *Text `json:"text,omitempty"`

    Image *Image `json:"image,omitempty"`

    Audio *Audio `json:"audio,omitempty"`

    Video *Video `json:"video,omitempty"`

    ....

}

拓展

发送消息肯定不止这几种类型,其它一些特殊样式的如卡片、系统提示信息、问卷、跳转等等。

上面的结构也是易于拓展的,只要定义不同的msgType及其对应的结构,前后端统一结构即可。

校验内容

敏感词服务校验,接口调用判定。

资金来往、索要联系方式等风险提示。

风险用户提示,审核服务,接口调用判定。

拉取消息

  1. 客户端根据since和limit来拉取消息,每次取本地最新消息的msgId作为since。
  2. 服务端从zset中拉取msgId大于since的消息(zrangeByScore),小于since的消息会从zset中删除。
    1. 大于since且在limit之间的消息不能删除,因为不能判定客户端正常收到这些消息。
    2. 每次删除since之前的消息,能保证删除的消息,一定是被客户端收到的(不然since不可能传过来)。
  3. 触发拉取消息时机:
    1. 收到普通push、静默push。厂商提供的push接口。
    2. 每间隔5s拉取消息

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值