本文共 5897 字,大约阅读时间需要 19 分钟。
在一个系统中,资源,数据会持续不断的更新。而用户如果需要知道这些数据的更新,就需要一个系统,将系统中不断更新的数据流,发送给相关的用户。
这个系统应该具备如下的几个功能:
针对这几个需求,来设计一个可灵活扩展的消息系统。
将系统拆分成2个部分:
当资源的更新,触发了资源上的消息产生规则,就会产生消息。对于资源的更新,可能会触发多条消息产生规则,产生多条通知,发给不同的用户不同的消息。所以这里每条消息产生规则,对应一个消息模版。
消息的产生规则,由动作触发规则(rule),接受者(recipient)2部分组成。
比如:
rule | recipient |
---|---|
somebody_@_somebody | user |
rule | recipient |
---|---|
somebody_comment_weibo | author |
rule | recipient |
---|---|
somebody_send_message | user |
rule | recipient |
---|---|
somebody_login | friend |
还有一种情况,当执行了某种操作,触发了多条条消息产生规则
比如:
当管理员A删除了一条微博,触发了2条消息产生规则rule | recipient |
---|---|
somebody_delete_weibo | author |
rule | recipient |
---|---|
somebody_delate_weibo | follower |
系统根据用户的订阅,将消息发送给订阅了消息的用户。
用户的订阅,是用户对具体资源(target / executor)上消息产生规则的订阅((executor + action) / executor + action + target)。这里用户订阅的是具体的资源对象。
比如:
特定资源 | 消息产生规则 |
---|---|
我(target) | somebody_@_someone |
特定资源 | 消息产生规则 |
---|---|
我的微博(target) | somebody_comment_weibo |
特定资源 | 消息产生规则 |
---|---|
我(target) | sombody_send_message |
特定资源 | 消息产生规则 |
---|---|
好友(executor) | somebody_login |
消息的发送方式分为系统推送,和用户拉取
当某个具体资源的更新,触发了这个资源上的消息产生规则,产生消息。系统再根据用户在这个资源上的订阅,将消息发送给订阅了这个资源的消息的用户。产生的消息和用户通过用户订阅关联起来。用户可以根据订阅的设置,来设置是否接收主动推送的消息。
根据以上的分析,可以知道,系统中有以下几个实体类:
资源可以是是系统中的各类对象模型
这里的资源可能是被操作的对象,也可能是动作的执行者。例如:
// 消息产生规则[ { 'rule': 'user_update_weibo', // 触发规则 'targetType': 'weibo', // 触发规则作用的对象类型 'relationship': 'follow', // 触发对象与订阅对象的关系 'role': 'user', // 订阅对象在系统中的角色 'obtainType': 0 // 消息的发送方式:0.推,1.拉 }, { 'rule': 'user_update_weibo', 'targetType': 'weibo', 'relationship': 'author', 'role': 'user', 'obtainType': 0 }, { 'rule': 'user_comment_weibo', 'targetType': 'weibo', 'relationship': 'author', 'role': 'user', 'obtainType': 0 }, { 'rule': 'user_delete_weibo', 'targetType': 'weibo', 'relationship': 'author', 'role': 'user', 'obtainType': 0 } { 'rule': 'user_delete_weibo', 'targetType': 'weibo', 'relationship': 'follow', 'role': 'user', 'obtainType': 0 }, { 'rule': 'user_delete_weibo', 'targetType': 'weibo', 'relationship': 'admin', 'role': 'admin', 'obtainType': 1 }, { 'rule': 'user_follow_someone', 'targetType': 'user', 'relationship': 'self', 'role': 'user', 'obtainType': 0 }, { 'rule': 'user_publish_weibo', 'targetType': 'user', 'relationship': 'follow', 'role': 'user', 'obtainType': 0 }, { 'rule': 'user_login', 'targetType': 'user', 'relationship': 'friend', 'role': 'user', 'obtainType': 0 }]
消息生成规则由如下几部分组成:
触发规则用一个字符串表示,作为规则的唯一标识,也可以从字面上直接看出消息的规则,便于理解。每条规则是一个主谓短语(executor_action),或者主谓宾短语(executor_action_target)。
消息产生规则作用于某一类资源。但是对于不同的用户,和资源的关系不同,收到的消息不同,所以生成消息的规则也不同。所以通过用户和资源的关系,分组资源的消息产生规则。记录触发规则作用的对象类型,可以通过对象类型,查出这个对象上所有的触发规则。
规则作用资源和订阅者之间的关联关系类别。当资源被创建时,或者用户和资源发生关联时,根据用户和资源的关系类型,订阅不同的消息规则。
对于不同角色的用户,对于同一种资源,需要配置的规则也不一样,比如不需要把管理员的订阅规则,保存到普通用户设置里。这里的role,可以和系统里的角色系统相关联,为不同的角色,配置不同的订阅规则。
消息产生规则相对固定,并且每次增加,需要实现相应的消息模版,无法通过增加配置自动生效。所以这里直接使用配置文件或者配置类保存信息,比较简单方便,不需要对外提供管理编辑的接口。
create table notify ( id int, rule varchar comment '消息产生规则', obtain_type int comment '消息的获取方式:0.推,1.拉', target_id int comment '消息产生规则作用的对象', target_type int comment '消息产生规则作用的对象类型', content varchar comment '消息内容', sender_id int comment '消息发送者id', sender_type int comment '消息发送者类型:0.系统,1.用户,...', notify_type int comment '消息类型:0.公告,1.新闻,2.活动,3.feed,...', create_time timestamp comment '消息创建时间') comment = '消息'
说明下几个重点的字段:
订阅消息的用户
create table subscribe ( id int, rule int comment '消息产生规则', target_id int comment '消息产生规则作用的对象', target_type int comment '消息产生规则作用的对象类型', create_time timestamp comment '订阅时间', valid int comment '订阅是否有效:0.无效,1有效') comment = '用户订阅'
保存具体用户订阅了哪些消息产生规则,以及针对这条规则,是否接收系统的主动推送create table subscribe_config ( id int, rule int comment '消息产生规则', enable_recieve int comment '针对这条规则,是否接收系统的主动推送:0.不接收,1.接收') comment = '用户订阅设置'
create table recipient_notify ( id int, recipient_id int comment '消息接收者id', notify_id int comment '消息id', create_time timestamp comment '消息创建时间', read_time timestamp comment '用户阅读时间') comment = '用户消息列表'
根据系统的运行方式,和系统建模。系统的服务需要以下几个功能:
getAllRuleByObjectType(objectType) 获取某类对象的所有消息产生规则
setPushConfig(user) 用户设置获取推送规则
设置用户推送规则,是否接受推送
设置用户订阅,将用户和消息产生规则和规则作用的具体对象关联
取消用户订阅
获取用户所有具体对象上的订阅
根据消息产生规则,创建消息,source是消息内容需要的所有数据
将消息保存到用户消息列表,同时发送推送消息
将消息保存到用户消息列表
获取用户订阅的所有消息产生规则
getUsersBySubscribe(subscribe) 查询所有订阅了这条订阅的用户
getNotifyBySubscribe(subscribe) 查询所有根据这条消息产生规则和作用目标,生成的消息
readRecipientNotify(now) 读消息列表
设置读取的消息的读取时间
时序图
消息的创建,订阅,推送,拉取Paste_Image.png
Paste_Image.png
转载地址:http://eruws.baihongyu.com/