メッセージ システムの設計と実装
文/JC_Huang (概要本の著者)
原文リンク: http://www.jianshu.com/p/f4d7827821f1
著作権は著者に属し、転載する場合は著者に連絡して許可を得て、「概要書の著者」とマークを付けてください。
まず、メッセージが市場でどのように実装されるかを見てみましょう。
Jianshuのメッセージシステムは主に2つのタイプに分かれています
ショートメッセージ
ショートメッセージの性質は、実際にはプライベートメッセージと同じであり、特定の情報内容を含むユーザーからユーザーに送信されるメッセージです。
リマインダー
リマインダーは、システムによって送信されるメッセージの形式です。コピーは固定されており、通常は特定のオブジェクトへのハイパーリンクがあります。
Zhihu は Jianshu と同じで、主に 2 つのタイプがあります:
プライベートメッセージ
Jianshu と同様に、ユーザーがユーザーにメッセージを送信できます。管理者からユーザーに送信されるメッセージにすることができます。
メッセージ
Zhihu メッセージは Jianshu のリマインダーよりも優れています。 Zhihu は、ユーザーの読書プレッシャーを軽減するために、複数の同様のメッセージを収集します。
2 つの製品の簡単な分析を通じて、これに基づいて、もう 1 つのメッセージ、つまりアナウンスを追加します。
アナウンスの主な性質は、システムがサイト上のすべてのユーザーが読むことができる特定のコンテンツを含むメッセージを送信することです。
メッセージには 3 つのカテゴリがあります:
Jianshu から一連のリマインダー サンプルを取得します。
文の構造を分析してください、リマインダーの内容は単なるものです
「誰が誰のものに何をするのか」
「誰かが誰かの何かで何かをする」
誰か = リマインダーのトリガー、または送信者、送信者としてマーク
何かをする = リマインダーのアクション、コメント、いいね、注目はすべて 1 つのアクションに属し、アクションとしてマーク
何か = リマインダーのアクションのオブジェクト、どの特定の記事それは、ターゲットとしてマークされています
誰かの = リマインダー アクションのオブジェクトの所有者、targetOwner
としてマークされています これは明らかです、送信者と targetOwner は Web サイトのユーザーであり、ターゲットは特定の記事がリマインダーの対象である場合、記事に限定されず、他にもある場合は、ターゲットが記事であるかそれ以外であるかをマークする targetType を追加する必要があります。アクションは固定されています。Web サイト全体でリマインダーをトリガーするアクションはいくつかしかありません: コメント、いいね、フォロー... (または企業がリマインダーを必要とするその他のアクション)
Zhihu を例に挙げます
プッシュの方が多いです特定の質問のフォロワーのリストを維持する必要があります。この質問をプッシュする条件がトリガーされると (たとえば、誰かが質問に回答するなど)、この通知が各フォロワーに送信されます。
プルはプッシュの逆で、少し面倒です。たとえば、ユーザーがオンラインになるたびに、各問題のイベント リストがポーリングされます。元のタイムスタンプよりも大きい場合は、それを取得します。
メッセージの分類に応じて異なる取得方法を使用します。:
メッセージが生成されると、メッセージは特定のメッセージ テーブルに保存されます。送信者がメッセージを作成した後、関心のある問題の表に従ってメッセージをプルし、それを独自のメッセージ キューに追加します。また、受信者を指定するか、受信者のメッセージ キューにメッセージを追加します。
購読
"サブスクライブ" サブスクライブ
:
サブスクリプション ターゲットtarget 記事が気に入った場合、購読アクションは記事を公開するときとは異なる場合があります。 記事が気に入ったら、更新情報やコメントを得るためにこの記事を購読していただければ幸いです。
記事を投稿するときに、この記事のコメント アクションを購読できればいいのにと思います。
この時点で、もう 1 つのパラメータが必要です。subscribReason
subscribeReason = like、actions = [update, comment]
subscribeReason = に対応します。 public 、アクションに対応 = [コメント]
ユーザーは独自のサブスクリプション設定を持つことができます。たとえば、すべてのお気に入りのアクションに対して、「I Don'」受け取りたくないのです。 たとえば、知っているリマインダーの設定
、ユーザーのリマインダー設定を保存します。 また、ユーザーがリマインダー設定を持っていない場合は、システムによって提供される一連のデフォルト設定を使用できます: defaultSubscriptionConfig
Aggregation
Zhihu は集計において優れた仕事をしました。彼らが達成したいかどうかを知る必要があります。これはかなり技術的です:
Web サイトのメッセージ (通知) システムは一般的にどのように実装されていますか?
関数のこの部分に関しては、まだ具体的な実装方法が決まっていないため、これ以上詳しく説明することはできません。 ⊙﹏⊙
5 つのエンティティ
createNotify (アナウンス | リマインド | メッセージ)
<code class="javascript">id : {type: <span class="hljs-string">'integer', primaryKey: <span class="hljs-literal">true}, <span class="hljs-comment">// 主键content : {type: <span class="hljs-string">'text'}, <span class="hljs-comment">// 消息的内容type : {type: <span class="hljs-string">'integer', required: <span class="hljs-literal">true, enum: [<span class="hljs-number">1, <span class="hljs-number">2, <span class="hljs-number">3]}, <span class="hljs-comment">// 消息的类型,1: 公告 Announce,2: 提醒 Remind,3:信息 Messagetarget : {type: <span class="hljs-string">'integer'}, <span class="hljs-comment">// 目标的IDtargetType : {type: <span class="hljs-string">'string'}, <span class="hljs-comment">// 目标的类型action : {type: <span class="hljs-string">'string'}, <span class="hljs-comment">// 提醒信息的动作类型sender : {type: <span class="hljs-string">'integer'}, <span class="hljs-comment">// 发送者的IDcreatedAt : {type: <span class="hljs-string">'datetime', required: <span class="hljs-literal">true}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
保存リマインド
メッセージ テーブルには、target
、targetType
フィールドが必要です。このリマインダーに関連付けられたオブジェクトを記録します。 action
フィールドには、リマインダーに関連付けられたアクションが記録されます。
たとえば、メッセージ: 「Xiao Ming が記事を気に入った」
その後:
<code class="javascript">target = <span class="hljs-number">123, <span class="hljs-comment">// 文章IDtargetType = <span class="hljs-string">'post', <span class="hljs-comment">// 指明target所属类型是文章sender = <span class="hljs-number">123456 <span class="hljs-comment">// 小明ID</span></span></span></span></span></span></code>
アナウンスとメッセージを保存
もちろん、Notify は保存もサポートしていますお知らせと情報。 content
フィールドは使用されますが、target
、targetType
、および action
フィールドは使用されません。
<code class="javascript">id : {type: <span class="hljs-string">'integer', primaryKey: <span class="hljs-literal">true}, <span class="hljs-comment">// 主键isRead : {type: <span class="hljs-string">'boolean', required: <span class="hljs-literal">true}, user : {type: <span class="hljs-string">'integer', required: <span class="hljs-literal">true}, <span class="hljs-comment">// 用户消息所属者notify : {type: <span class="hljs-string">'integer', required: <span class="hljs-literal">true} <span class="hljs-comment">// 关联的NotifycreatedAt : {type: <span class="hljs-string">'datetime', required: <span class="hljs-literal">true}</span></span></span></span></span></span></span></span></span></span></span></span></span></code>
UserNotify を使用して、リマインダー (通知) の特定のコンテンツに関連付けられたユーザーのメッセージ キューを保存します。
UserNotify は主に 2 つの方法で作成されます:
<code class="javascript">target : {type: <span class="hljs-string">'integer', required: <span class="hljs-literal">true}, <span class="hljs-comment">// 目标的IDtargetType : {type: <span class="hljs-string">'string', required: <span class="hljs-literal">true}, <span class="hljs-comment">// 目标的类型action : {type: <span class="hljs-string">'string'}, <span class="hljs-comment">// 订阅动作,如: comment/like/post/update etc.user : {type: <span class="hljs-string">'integer'},createdAt : {type: <span class="hljs-string">'datetime', required: <span class="hljs-literal">true}</span></span></span></span></span></span></span></span></span></span></span></code>
サブスクリプションは、Notify テーブルから UserNotify にメッセージをプルするための前提条件です。ユーザーはまず特定のターゲットのアクションをサブスクライブし、次にこの Only を生成します。ユーザーはターゲットのアクションを通知されます。
例: 「Xiao Ming は製品 A のコメントに注目しました」、データは次のように表現されます:
<code class="javascript">target: <span class="hljs-number">123, <span class="hljs-comment">// 产品A的IDtargetType: <span class="hljs-string">'product',action: <span class="hljs-string">'comment',user: <span class="hljs-number">123 <span class="hljs-comment">// 小明的ID</span></span></span></span></span></span></code>
このように、製品 A で生成されたすべてのコメントにより Xiao への通知が生成されます。明。
<code class="javascript">action: {type: <span class="hljs-string">'json', required: <span class="hljs-literal">true}, <span class="hljs-comment">// 用户的设置user: {type: <span class="hljs-string">'integer'}</span></span></span></span></code>
ユーザーごとにサブスクリプションの習慣が異なる場合があります。このテーブルでは、ユーザーは特定のアクションをサブスクライブするかどうかを一律に設定できます。デフォルトでは、システムによって提供されるデフォルト構成が使用されます。
<code class="javascript">defaultSubscriptionConfig: { <span class="hljs-string">'comment' : <span class="hljs-literal">true, <span class="hljs-comment">// 评论 <span class="hljs-string">'like' : <span class="hljs-literal">true, <span class="hljs-comment">// 喜欢}</span></span></span></span></span></span></code>
このモデルのセットでは、
targetType
とaction
は必要に応じて拡張できます。各アクションのリマインダーをさらに追加します:hate
が嫌われた、update
が更新されたなど。
<code class="javascript"><span class="hljs-comment">// 提醒关联的目标类型targetType: { PRODUCT : <span class="hljs-string">'product', <span class="hljs-comment">// 产品 POST : <span class="hljs-string">'post' <span class="hljs-comment">// 文章},<span class="hljs-comment">// 提醒关联的动作action: { COMMENT : <span class="hljs-string">'comment', <span class="hljs-comment">// 评论 LIKE : <span class="hljs-string">'like', <span class="hljs-comment">// 喜欢},<span class="hljs-comment">// 订阅原因对应订阅事件reasonAction: { <span class="hljs-string">'create_product' : [<span class="hljs-string">'comment', <span class="hljs-string">'like'] <span class="hljs-string">'like_product' : [<span class="hljs-string">'comment'], <span class="hljs-string">'like_post' : [<span class="hljs-string">'comment'],},<span class="hljs-comment">// 默认订阅配置defaultSubscriptionConfig: { <span class="hljs-string">'comment' : <span class="hljs-literal">true, <span class="hljs-comment">// 评论 <span class="hljs-string">'like' : <span class="hljs-literal">true, <span class="hljs-comment">// 喜欢}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
createAnnounce (content, sender)
createRemind(target, targetType, action, sender 、content)
createMessage(content, sender,Receiver)
pullAnnounce(user)
lastTime
lastTime
をフィルター条件として使用して、Notify のアナウンス情報をクエリします pullRemind(user)
target
、targetType
、action
、createdAt
を介して Notify テーブルをクエリし、サブスクライブされた Notify レコードを取得します。 (サブスクリプション時刻はリマインダーの作成時刻よりも前である必要があることに注意してください) subscribe(user, target, targetType,reason)
actions
cancelSubscription (user, target, targetType)
user
、target
、targetType
getSubscriptionConfig に対応する 1 つ以上のレコードを削除します(userID)
updateSubscriptionConfig(userID)
getUserNotify(userID)
読み取り(ユーザー、通知ID)
製品の作成後に NotifyService.subscribe
メソッドを呼び出し、
メソッドを呼び出して、製品のレビュー後に呼び出すことができます。 NotifyService.createRemind
メソッド、
はその後、ユーザーがシステムにログインするときに NotifyService.pullRemind
メソッドを呼び出します。または、ユーザーがメッセージ キューをクエリするときに、
は最後に NotifyService.getUserNotify
メソッドを呼び出します。
管理者から送信 アナウンス時が作成され、NotifyService.createAnnounce
メソッドが呼び出され、
次に、ユーザーがシステムにログインするとき、または別の時点で NotifyService.pullAnnounce
メソッドが呼び出され、最後にユーザーがシステムにログインしたときに
メソッドが呼び出されます。メッセージキューをクエリします。 NotifyService.getUserNotify
情報を作成するには、
を直接呼び出すだけです これNotifyService.createMessage
次回ユーザーがメッセージ キューをクエリするときに、この情報がクエリされます。