Design and implementation of message system
Wen/jc_huang (author of Jane's book)
Original link: http://www.jianshu.com/p/f4d7827821f1
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".
Product analysis
First, let's take a look at how the message is implemented on the market.
Pinterest
The message system of Jane's book is mainly divided into two kinds
Jane
The nature of the Jane is in fact the same as the private message, is the user sent to the user a news, there is specific information content.
Jane Letters Letter
Remind
A reminder is a message sent by the system whose copy format is fixed and has a hyperlink to a particular object.
Pinterest reminders
Know
As with the book of Jane, there are two main types:
Private messages
As with a book, a message that the user sends to the user can also be a message that the administrator sends to the user.
Private messages are known
News
The message is better than a simple reminder that a lot of similar messages will come together to ease the user's reading pressure.
Know the News
Three categories of messages
Through the simple analysis of the two products, we can conclude that there are two kinds of classification of their messages, on this basis, we add one kind: announcement.
The main nature of the announcement is that the system sends a message containing specific content that all users in the station can read.
So, there are three categories of messages:
- Announcement announce
- Remind Remind
- Message messages
Linguistic analysis of Reminders
We take a set of reminder samples from the book:
- 3dbe1bd90774 followed you.
- Magicdawn liked your article. Three ways to achieve single sign-on
- Unscrupulous programs like your article "How to design user Rights control based on restful API?" 》
- Alexcc4 liked your article, "Implement unit Test in Nodejs"
- How do you design user rights control based on restful API? Received a Cnlinjie comment in the "
- Your article "session principle" has been added to the topic "iOS development"
Analysis of sentence structure, the content of the reminder is nothing more than
"Who does what to the same thing that belongs to whom?"
"someone do something in someone ' s something"
someone = trigger of the reminder, or sender, marked as sender
Do something = action of reminders, comments, likes, and concerns are all part of an action, marked as action
something = The Action object of the reminder, which is specific to which article, marked as target
Someone ' s = owner of the action object of the alert, marked as Targetowner
It is clear that sender and Targetowner are users of the site, and target is specific to which article, if the object of the reminder is not confined to the article, there are other words, you need to add a targettype, to mark the goal is the article or something else. And action, is fixed, the whole site will trigger reminders of the action may only be those: comments, likes, concerns ..... (or other actions that the business needs to alert)
Two ways to get messages
In the case of knowledge
Push is more common, you need to maintain a list of followers for a particular issue, and send this notification to each of the followers whenever the condition that triggers the problem is pushed (for example, someone answers a question).
Pull the relatively troublesome point, that is, push the reverse, for example, each user has a list of concerns, each time the user on the line, each issue polling, when the issue of the list of events more than my original time stamp of information to pull.
we use different methods of obtaining information according to different classifications of messages :
Announcements and reminders, which are appropriate for the use of pull, after the message is generated, there is a message table in which the user pulls the message at a specific time based on the table of their concern, and then adds it to their message queue.
Information, suitable for use push, after the sender to create a message, at the same time specify the recipient, add the message to the receiver's message queue.
Subscription
Depending on how you pull the reminder, you need to maintain a list of things that concern you.
This behavior, we call it:"subscribe to"subscribe
a subscription has the following three core attributes :
- Destination target for the subscription
- The target type of the subscription TargetType
- Subscribe to Action action
For example, I published an article, then I will subscribe to the article "xxx" comment action, so the article "xxx" Every person commented, you need to send a reminder to tell me.
The rules for subscriptions can also be extended
I like an article, and I published an article, the subscription may not be the same action.
Like an article, I hope I subscribe to this article update, comment on the action.
and published an article, I hope I just subscribe to this article Comment action.
One more parameter is required: Subscribreason
Different Subscribreason, which corresponds to an array of actions,
Subscribreason = like, corresponds to actions = [UPDATE, comments]
Subscribreason = published, corresponds to actions = [comments]
The rules for subscriptions can also be extended
Users may have their own subscription settings, for example, for all the likes of the action, I do not want to receive.
such as Knewone's reminder settings
Knewone Reminder Settings
So we need to maintain a table:subscriptionconfig, to store the user's reminder settings.
Also, when users do not have a reminder setting, they can use the system-provided set of default settings:defaultsubscriptionconfig
Polymerization
If I published an article "XXX", when I am not online, was commented 10 times, when I was on the line, should be received 10 messages similar to: "Who who commented on your article" XXX "?
Or should receive a message: "A, B, C, ding ... Commented on your article "XXX"?
Knowing that they are doing well on the aggregations, it is quite technical to know that they are going to achieve this:
How is the information mechanism designed and planned in the technology?
How does the Web site's message (notification) system generally be implemented?
On this part of the function, we do not have a specific implementation method, for the time being unable to speak more detailed. ⊙﹏⊙
Five entities
With the above analysis, you probably know what entity classes are needed to do this message system:
- User Message Queuing usernotify
- Users user
- Subscribe to Subscription
- Subscription Settings Subscriptionconfig
- Message Notify
- Notice announce
- Remind Remind
- Message message
Behavioral decomposition
Having said so much, tidy up some of the behavior of the entire message flow:
- System or administrator, create a message
- Createnotify (Make announce | remind | message)
- Users, subscribing to messages, canceling subscriptions
- Subscribe, cancelsubscription
- User Management Subscription Settings
- Getsubscriptionconfig, Updatesubscriptionconfig
- User, Pull Message
- Pullnotify (Pull announce | remind | message | all)
- User, querying Message Queuing
- Getusernotify (Get announce | remind | message | all)
- User Read Message
>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>
Model design
Notify
ID: {type:' Integer ', PrimaryKey:True},//primary key content: {type: // Content type: {type: true, enum: [1, 2, 3]}, //message type, 1: Announcement announce,2: Reminder remind,3: Information messagetarget: {type: ' integer '}, Target's Idtargettype: {type: //target type action: {type: Span class= "hljs-string" > ' string '}, //alert message action type sender: {type: //sender Idcreatedat: {type: true}
Save Remind
The message table, which we need target
, targetType
fields, to record the object that the reminder is associated with. And the action
field, the action associated with the reminder is recorded.
such as the message: "Xiao Ming liked the article"
The
123, // 文章IDtargetType = 'post', // 指明target所属类型是文章sender = 123456 // 小明ID
Save Announce and Message
Of course, notify also supports storing announcements and information. They use content
fields, not fields target
targetType
action
.
Usernotify
id 'integer', primaryKey: true}, // 主键isRead : {type: 'boolean', required: true}, user : {type: 'integer', required: true}, // 用户消息所属者notify : {type: 'integer', required: true} // 关联的NotifycreatedAt : {type: 'datetime', required: true}
We use Usernotify to store the user's message queue, which associates a reminder (Notify) with the specific content.
The creation of usernotify, mainly through two channels:
- Traversal subscriptions (Subscription) Table pull announcements (announce) and reminders (Remind) are created when
- Created immediately after the new information (message).
Subscription
target 'integer', required: true}, // 目标的IDtargetType : {type: 'string', required: true}, // 目标的类型action : {type: 'string'}, // 订阅动作,如: comment/like/post/update etc.user : {type: 'integer'},createdAt : {type: 'datetime', required: true}
Subscription, is the premise of pulling messages from notify to Usernotify, the user first subscribes to a certain action of a target, after which the message that generates this action of the target will be notified to the user.
such as: "Xiao Ming followed the review of Product A", the data expressed as:
123, // 产品A的IDtargetType: 'product',action: 'comment',user: 123 // 小明的ID
In this way, every comment produced under Product A will produce a notification to the small clear.
Subscriptionconfig
'json', required: true}, // 用户的设置user: {type: 'integer'}
Different users may have an unusual subscription habit, in which the user can unify settings for whether or not to subscribe to an action. The default is to use the default configuration provided by the system:
defaultSubscriptionConfig: { 'comment' : true, // 评论 'like' : true, // 喜欢}
In this model, can be targetType
action
expanded according to the needs of, for example, we can also add more than a few action reminders: hate
be trampled, update
be updated .... Such.
Configuration file Notifyconfig
Alert associated Target type targettype: {PRODUCT:' Product ',Product POST:' Post '//article},//reminder associated Action action: {comment: ' comment ', //comment like: ' like ', //likes},//subscription cause corresponding subscription event reasonaction: { ' comment ', ' like ') ' like_product ': [ ' comment '], ' like _post ': [ ' comment '],},//default subscription configuration defaultsubscriptionconfig: { Span class= "hljs-string" > ' comment ': true, //comments ' like ': true, //likes}
Service Layer Notifyservice
Notifyservice has the following methods:
- 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)
The processing logic for each method is as follows:
Createannounce (content, Sender)
- Insert an announcement record into the Notify table
Createremind (target, targetType, action, sender, content)
- Insert a reminder record into the Notify table
CreateMessage (content, sender, receiver)
- Insert a message record into the Notify table
- Inserts a record into the Usernotify table and associates the newly created notify
Pullannounce (user)
- Get the most recent announcement information from Usernotify when you created it:
lastTime
- Use
lastTime
as a filter to query notify announcement information
- Create a new usernotify and associate a query with the announcement information
Pullremind (user)
- Query user's subscription table, get a series of user's subscription record
target
get the Notify record of the subscription by targetType
querying action
the createdAt
notify table for each subscription record. (Note that subscription time must be before the reminder creation time)
- Queries the user's profile subscriptionconfig, and if not, uses the default configuration Defaultsubscriptionconfig
- Use subscription configuration to filter queries out of notify
- New usernotify with filtered notify as an association
Subscribe (user, target, targetType, reason)
- Through reason, query notifyconfig, get the corresponding action group:
actions
- Iterate through action groups, create a new subscription record for each action
Cancelsubscription (user, target, targetType)
- Delete
user
, target
targetType
a corresponding record, or multiple records
Getsubscriptionconfig (UserID)
- Query the Subscriptionconfig table to get the user's subscription configuration
Updatesubscriptionconfig (UserID)
- Update the user's subscriptionconfig record
Getusernotify (UserID)
- Get the user's message list
Read (user, notifyids)
- Update the specified notify, set the Isread property to True
Timing Diagram
Reminders for subscriptions, create, pull
Reminders for subscriptions, create, pull
We can call the method after the product is created, NotifyService.subscribe
Then call the method after the product is commented NotifyService.createRemind
,
Then the user login system or some other time to invoke the NotifyService.pullRemind
method,
Finally, the method is called when the user queries the message queue NotifyService.getUserNotify
.
Creation, pull of announcements
Creation, pull of announcements
When the administrator sends an announcement, the NotifyService.createAnnounce
method is called,
Then call the method at the user's login system or some other time NotifyService.pullAnnounce
,
Finally, the method is called when the user queries the message queue NotifyService.getUserNotify
.
Creation of information
Creation of information
The creation of information, just call the NotifyService.createMessage
method directly, you can
This information is queried the next time the user queries the message queue.