消息系統設計與實現「下篇」

原文連接:BlueSun | 消息系統設計與實現「上篇」javascript

模型設計

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字段,則記錄該條提醒所關聯的動做。
好比消息:「小明喜歡了文章」
則:java

target = 123,  // 文章ID
targetType = 'post',  // 指明target所屬類型是文章
sender = 123456  // 小明ID

Save Announce and Message
固然,Notify還支持存儲公告和信息。它們會用到content字段,而不會用到targettargetTypeaction字段。node

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的建立,主要經過兩個途徑:git

  1. 遍歷訂閱(Subscription)表拉取公告(Announce)和提醒(Remind)的時候建立github

  2. 新建信息(Message)以後,馬上建立。json

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的評論」,數據表現爲:post

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

這樣,產品A下產生的每一條評論,都會產生通知給小明瞭。ui

SubscriptionConfig

action: {type: 'json', required: true},   // 用戶的設置
user: {type: 'integer'}

不一樣用戶可能會有不同的訂閱習慣,在這個表中,用戶能夠統一針對某種動做進行是否訂閱的設置。而默認是使用系統提供的默認配置:spa

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)

  1. 往Notify表中插入一條公告記錄

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

  1. 往Notify表中插入一條提醒記錄

createMessage(content, sender, receiver)

  1. 往Notify表中插入一條信息記錄

  2. 往UserNotify表中插入一條記錄,並關聯新建的Notify

pullAnnounce(user)

  1. 從UserNotify中獲取最近的一條公告信息的建立時間: lastTime

  2. lastTime做爲過濾條件,查詢Notify的公告信息

  3. 新建UserNotify並關聯查詢出來的公告信息

pullRemind(user)

  1. 查詢用戶的訂閱表,獲得用戶的一系列訂閱記錄

  2. 經過每一條的訂閱記錄的targettargetTypeactioncreatedAt去查詢Notify表,獲取訂閱的Notify記錄。(注意訂閱時間必須早於提醒建立時間)

  3. 查詢用戶的配置文件SubscriptionConfig,若是沒有則使用默認的配置DefaultSubscriptionConfig

  4. 使用訂閱配置,過濾查詢出來的Notify

  5. 使用過濾好的Notify做爲關聯新建UserNotify

subscribe(user, target, targetType, reason)

  1. 經過reason,查詢NotifyConfig,獲取對應的動做組:actions

  2. 遍歷動做組,每個動做新建一則Subscription記錄

cancelSubscription(user, target ,targetType)

  1. 刪除usertargettargetType對應的一則或多則記錄

getSubscriptionConfig(userID)

  1. 查詢SubscriptionConfig表,獲取用戶的訂閱配置

updateSubscriptionConfig(userID)

  1. 更新用戶的SubscriptionConfig記錄

getUserNotify(userID)

  1. 獲取用戶的消息列表

read(user, notifyIDs)

  1. 更新指定的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

相關文章
相關標籤/搜索