原文连接:BlueSun | 消息系统设计与实现「上篇」javascript
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
消息表,咱们须要target
、targetType
字段,来记录该条提醒所关联的对象。而action
字段,则记录该条提醒所关联的动做。
好比消息:「小明喜欢了文章」
则:java
target = 123, // 文章ID targetType = 'post', // 指明target所属类型是文章 sender = 123456 // 小明ID
Save Announce and Message
固然,Notify还支持存储公告和信息。它们会用到content
字段,而不会用到target
、targetType
、action
字段。node
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的建立,主要经过两个途径:git
遍历订阅(Subscription)表拉取公告(Announce)和提醒(Remind)的时候建立github
新建信息(Message)以后,马上建立。json
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的评论」,数据表现为:post
target: 123, // 产品A的ID targetType: 'product', action: 'comment', user: 123 // 小明的ID
这样,产品A下产生的每一条评论,都会产生通知给小明了。ui
action: {type: 'json', required: true}, // 用户的设置 user: {type: 'integer'}
不一样用户可能会有不同的订阅习惯,在这个表中,用户能够统一针对某种动做进行是否订阅的设置。而默认是使用系统提供的默认配置:spa
defaultSubscriptionConfig: { 'comment' : true, // 评论 'like' : true, // 喜欢 }
在这套模型中,
targetType
、action
是能够根据需求来扩展的,例如咱们还能够增长多几个动做的提醒:hate
被踩、update
被更新....诸如此类。设计
// 提醒关联的目标类型 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, // 喜欢 }
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)
查询用户的订阅表,获得用户的一系列订阅记录
经过每一条的订阅记录的target
、targetType
、action
、createdAt
去查询Notify表,获取订阅的Notify记录。(注意订阅时间必须早于提醒建立时间)
查询用户的配置文件SubscriptionConfig,若是没有则使用默认的配置DefaultSubscriptionConfig
使用订阅配置,过滤查询出来的Notify
使用过滤好的Notify做为关联新建UserNotify
subscribe(user, target, targetType, reason)
经过reason,查询NotifyConfig,获取对应的动做组:actions
遍历动做组,每个动做新建一则Subscription记录
cancelSubscription(user, target ,targetType)
删除user
、target
、targetType
对应的一则或多则记录
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