资讯专栏INFORMATION COLUMN

消息系统设计与实现「下篇」

simon_chen / 3234人阅读

摘要:比如消息小明喜欢了文章则文章指明所属类型是文章小明当然,还支持存储公告和信息。如小明关注了产品的评论,数据表现为产品的小明的这样,产品下产生的每一条评论,都会产生通知给小明了。

原文链接:BlueSun | 消息系统设计与实现「上篇」

模型设计 Notify
id            : {type: "integer", primaryKey: true},        // 主键
content     : {type: "text"},    // 消息的内容
type        : {type: "integer", required: true, enum: [1, 2, 3]},  // 消息的类型,1: 公告 Announce,2: 提醒 Remind,3:信息 Message
target      : {type: "integer"},    // 目标的ID
targetType  : {type: "string"},    // 目标的类型
action      : {type: "string"},    // 提醒信息的动作类型
sender      : {type: "integer"},    // 发送者的ID
createdAt    : {type: "datetime", required: true}

Save Remind
消息表,我们需要targettargetType字段,来记录该条提醒所关联的对象。而action字段,则记录该条提醒所关联的动作。
比如消息:「小明喜欢了文章」
则:

target = 123,  // 文章ID
targetType = "post",  // 指明target所属类型是文章
sender = 123456  // 小明ID

Save Announce and Message
当然,Notify还支持存储公告和信息。它们会用到content字段,而不会用到targettargetTypeaction字段。

UserNotify
id            : {type: "integer", primaryKey: true},        // 主键
isRead      : {type: "boolean", required: true},   
user        : {type: "integer", required: true},  // 用户消息所属者
notify      : {type: "integer", required: true}   // 关联的Notify
createdAt    : {type: "datetime", required: true}

我们用UserNotify来存储用户的消息队列,它关联一则提醒(Notify)的具体内容。
UserNotify的创建,主要通过两个途径:

遍历订阅(Subscription)表拉取公告(Announce)和提醒(Remind)的时候创建

新建信息(Message)之后,立刻创建。

Subscription
target      : {type: "integer", required: true},    // 目标的ID
targetType  : {type: "string", required: true},    // 目标的类型
action      : {type: "string"},   // 订阅动作,如: comment/like/post/update etc.
user        : {type: "integer"},
createdAt    : {type: "datetime", required: true}

订阅,是从Notify表拉取消息到UserNotify的前提,用户首先订阅了某一个目标的某一个动作,在此之后产生这个目标的这个动作的消息,才会被通知到该用户。
如:「小明关注了产品A的评论」,数据表现为:

target: 123,  // 产品A的ID
targetType: "product",
action: "comment",
user: 123  // 小明的ID

这样,产品A下产生的每一条评论,都会产生通知给小明了。

SubscriptionConfig
action: {type: "json", required: true},   // 用户的设置
user: {type: "integer"}

不同用户可能会有不一样的订阅习惯,在这个表中,用户可以统一针对某种动作进行是否订阅的设置。而默认是使用系统提供的默认配置:

defaultSubscriptionConfig: {
  "comment"   : true,    // 评论
  "like"      : true,    // 喜欢
}

在这套模型中,targetTypeaction是可以根据需求来扩展的,例如我们还可以增加多几个动作的提醒:hate被踩、update被更新....诸如此类。

配置文件 NotifyConfig
// 提醒关联的目标类型
targetType: {
  PRODUCT : "product",    // 产品
  POST    : "post"    // 文章
},

// 提醒关联的动作
action: {
  COMMENT   : "comment",  // 评论
  LIKE      : "like",     // 喜欢
},

// 订阅原因对应订阅事件
reasonAction: {
  "create_product"  : ["comment", "like"]
  "like_product"    : ["comment"],
  "like_post"       : ["comment"],
},

// 默认订阅配置
defaultSubscriptionConfig: {
  "comment"   : true,    // 评论
  "like"      : true,    // 喜欢
}
服务层 NotifyService NotifyService拥有以下方法:

createAnnounce(content, sender)

createRemind(target, targetType, action, sender, content)

createMessage(content, sender, receiver)

pullAnnounce(user)

pullRemind(user)

subscribe(user, target, targetType, reason)

cancelSubscription(user, target ,targetType)

getSubscriptionConfig(userID)

updateSubscriptionConfig(userID)

getUserNotify(userID)

read(user, notifyIDs)

各方法的处理逻辑如下:

createAnnounce(content, sender)

往Notify表中插入一条公告记录

createRemind(target, targetType, action, sender, content)

往Notify表中插入一条提醒记录

createMessage(content, sender, receiver)

往Notify表中插入一条信息记录

往UserNotify表中插入一条记录,并关联新建的Notify

pullAnnounce(user)

从UserNotify中获取最近的一条公告信息的创建时间: lastTime

lastTime作为过滤条件,查询Notify的公告信息

新建UserNotify并关联查询出来的公告信息

pullRemind(user)

查询用户的订阅表,得到用户的一系列订阅记录

通过每一条的订阅记录的targettargetTypeactioncreatedAt去查询Notify表,获取订阅的Notify记录。(注意订阅时间必须早于提醒创建时间)

查询用户的配置文件SubscriptionConfig,如果没有则使用默认的配置DefaultSubscriptionConfig

使用订阅配置,过滤查询出来的Notify

使用过滤好的Notify作为关联新建UserNotify

subscribe(user, target, targetType, reason)

通过reason,查询NotifyConfig,获取对应的动作组:actions

遍历动作组,每一个动作新建一则Subscription记录

cancelSubscription(user, target ,targetType)

删除usertargettargetType对应的一则或多则记录

getSubscriptionConfig(userID)

查询SubscriptionConfig表,获取用户的订阅配置

updateSubscriptionConfig(userID)

更新用户的SubscriptionConfig记录

getUserNotify(userID)

获取用户的消息列表

read(user, notifyIDs)

更新指定的notify,把isRead属性设置为true

时序图 提醒的订阅、创建、拉取

我们可以在产品创建之后,调用NotifyService.subscribe方法,
然后在产品被评论之后调用NotifyService.createRemind方法,
再就是用户登录系统或者其他的某一个时刻调用NotifyService.pullRemind方法,
最后在用户查询消息队列的时候调用NotifyService.getUserNotify方法。

公告的创建、拉取

在管理员发送了一则公告的时候,调用NotifyService.createAnnounce方法,
然后在用户登录系统或者其他的某一个时刻调用NotifyService.pullAnnounce方法,
最后在用户查询消息队列的时候调用NotifyService.getUserNotify方法。

信息的创建


信息的创建,只需要直接调用NotifyService.createMessage方法就可以了,
在下一次用户查询消息队列的时候,就会查询这条信息。

如果本文对您有用
请不要吝啬你们的Follow与Start
这会大大支持我们继续创作

「Github」
MZMonster :@MZMonster
JC_Huang :@JerryC8080

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78924.html

相关文章

  • 消息系统设计实现「上篇」

    摘要:原文链接消息系统设计与实现上篇由于文章篇幅较长,而作者精力有限,不希望这么早就精尽人亡,故分成上下篇来写消息系统的设计与实现。更新于关联文章消息系统设计与实现下篇如果本文对您有用请不要吝啬你们的与这会大大支持我们继续创作 原文链接:Bluesun | 消息系统设计与实现「上篇」 由于文章篇幅较长,而作者精力有限,不希望这么早就精尽人亡,故分成上下篇来写消息系统的设计与实现。上篇主要讲...

    v1 评论0 收藏0
  • 从零到一,撸一个在线斗地主(下篇)

    摘要:原文从零到一,撸一个在线斗地主下篇作者上篇回顾我们说了斗地主游戏的渲染展示部分,最后也讲了下中交互的情况,下篇的重点就是游戏逻辑。 原文:从零到一,撸一个在线斗地主(下篇) | AlloyTeam作者:TAT.vorshen 上篇回顾:我们说了斗地主游戏的渲染展示部分,最后也讲了下canvas中交互的情况,下篇的重点就是游戏逻辑。 逻辑主要分成两块:流程逻辑和扑克牌对比逻辑。 gith...

    CloudDeveloper 评论0 收藏0
  • 浅谈架构是为了什么 (上)

    摘要:前言架构是一款软件从到的演变过程。并非是上来就可以承载什么亿级访问的牛架构什么的。这是软性架构,考虑扩展性。实际程序员与架构师不分家。设计架构设计覆盖一款应用运行的各个方面。架构并不是一个多么神秘的职业。虽然敌不过大厂的架构。 showImg(https://segmentfault.com/img/bVbf3Tg?w=1080&h=708); 前言 架构是一款软件从0到100的演变过...

    宠来也 评论0 收藏0
  • 浅谈架构是为了什么 (上)

    摘要:前言架构是一款软件从到的演变过程。并非是上来就可以承载什么亿级访问的牛架构什么的。这是软性架构,考虑扩展性。实际程序员与架构师不分家。设计架构设计覆盖一款应用运行的各个方面。架构并不是一个多么神秘的职业。虽然敌不过大厂的架构。 showImg(https://segmentfault.com/img/bVbf3Tg?w=1080&h=708); 前言 架构是一款软件从0到100的演变过...

    channg 评论0 收藏0
  • 浅谈架构是为了什么 (上)

    摘要:前言架构是一款软件从到的演变过程。并非是上来就可以承载什么亿级访问的牛架构什么的。这是软性架构,考虑扩展性。实际程序员与架构师不分家。设计架构设计覆盖一款应用运行的各个方面。架构并不是一个多么神秘的职业。虽然敌不过大厂的架构。 showImg(https://segmentfault.com/img/bVbf3Tg?w=1080&h=708); 前言 架构是一款软件从0到100的演变过...

    nifhlheimr 评论0 收藏0

发表评论

0条评论

simon_chen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<