blog

IM Share:大量のオフライン・メッセージの確実な配信をエレガントに実現する方法

IMチャットメッセージの信頼性の高い配信は、すべてのオンライン製品が考慮しなければならないホットなIM技術的問題です。 IMチャットメッセージは、確実に配信されることを保証することができ、ユーザーにと...

Sep 30, 2020 · 10 min. read
シェア

私はあなた方をよく知っていますから。

IMチャットメッセージの信頼性の高い配信は、すべてのオンライン製品が考慮しなければならないホットなIM技術的な問題です。

IMチャットメッセージは、信頼性の高い配信を保証することができ、ユーザーにとって、それは銀行にお金を入れているようなものです盗まれることを恐れていない、それは信頼の問題です。ユーザーが明確にチャットメッセージが配信されることを保証することができないことを認識することができます場合は、誰があなたのアプリを使用して喜んで、誰が自分の言葉は風と離れて浮遊雲のようになることを望んでいない、想像してみてください。

結局のところ、IMチャットは、多くの場合、それは時間の無駄ですが、常に重要な瞬間があります - そのような女神に告白するなど、修飾された舐める犬は女神がメッセージを見逃すことを望んではならないように。

したがって、メッセージの確実な配信はすべてのIM製品の基礎であり、IM開発者がたゆまず追求している技術目標でもあります。

この記事では、オフラインメッセージの確実な配信を前提に、ユーザーの体験が低下しないよう、筆者自身のIM開発プロセスを実際に要約し、大量のオフラインチャットメッセージを共有します。

- インスタントメッセージ/プッシュ技術開発交流グループ5:【推奨

- インスタントメッセージ/プッシュ型技術開発交流会5:【おすすめ】モバイル側のIM開発入門記事512477170開発

以下はマスコミに掲載された記事の一部です。

クライアントの視点からモバイルIMのメッセージの信頼性と配信メカニズム

モバイルIMにおける大規模グループメッセージの効率性とリアルタイム配信を確保するには?

IMメッセージ配信保証メカニズム:オンライン・リアルタイム・メッセージの確実な配信

IMメッセージ配信保証メカニズム:オフライン・メッセージの確実な配信

IMリアルタイムメッセージのタイミングと一貫性を保証するには?

IMメッセージのタイミングを保証する低コストのアプローチ

IMリアルタイム・メッセージのタイミングと一貫性を確保するには?

モバイルIMログイン時にデータをプルする際のトラフィックを節約する方法

完全に自己開発されたIMのための「失敗リトライ」メカニズムを設計するには?

私はあなた方をよく知っていますから。

ある女神にずっと片思いしていて、ついに勇気を出してラブレターを書きました。でも、どう表現すれば女神の心を動かせるのでしょう?浅はかな気持ちで四書五経を読み、唐詩と宋詩を暗記し、四大名作を読んだので、すでにお腹の中には詩があります。週末に丸一日瞑想してから七行詩を書くと、世の中の勢いに衝撃を受けたわけではありませんが、行間を流れる思想の真摯な愛だけでなく、歌や詩も、きっと女神に感動してもらえると信じて、携帯電話を喜んで発信します。

一分後、携帯電話の画面を見つめて、女神からの返事を待っています。

一分一秒を待つのは、一年を待つのと同じくらい長い。

1時間経っても音沙汰なし。もしかしたら、何かと忙しくて、携帯電話を見ていなかったのかも!

1日が経過し、そわそわ、待つことは一種の痛みを伴う苦悩であり、絡み合ったロールの心の中で期待と苦悩は、いくつかの瞬間があり、さらには女神がすぐに自分自身を拒否することを願っているので、彼らは安心することができます!お茶とご飯味気ない、何日も不眠症、一日中魂。

一ヶ月後、死んだ心。

半年後、女神は結婚し、祝福に行くために結婚式の日。席も飲み物の群衆で、少し酔って、女神に乾杯:あなたを祝福し、私はあなたのような女性に会うことを願っています。女神はまず凍りつき、笑顔を消し、頭を下げ、大きな赤い絨毯を見て、長いため息をつき、こう言いました!数秒間空気がよどみ、女神は無理に明るい顔をした:これからは、それぞれの良い、乾杯!

私は振り返って自分の席に戻り、携帯電話を手に取り、アプリを開き、送信されたラブレターを見て、すべてが昨日のことのようですが、物語の脚本は他の誰かによって書かれている、泣きたく、ため息をつく神、なぜあなたは私にこのようなトリックをしますか?なぜ私は女神にメッセージを送ったああを受信しませんでした!

家に帰るために失われた魂は、アルコールの強い効果で、自分自身を麻酔するためにルーズベルト10のいくつかのボトルの冷蔵庫から、睡眠に混乱。

翌日、私は目を覚ました、私は真実を理解する:IMシステムのために、メッセージが最初の場所で常に到達する必要があります!

上記はナンセンスです、以下は本文を開始します。

、メッセージを達成するためにオフラインメッセージの完全な量で到達する必要があります!

IMシステムをリファクタリングする場合、メッセージが常に届くようにするために、前世代の設計のペインポイントの1つを解決する必要があります。

メッセージが確実に配信されるためのオフライン・メッセージング・フロー

こうすることを考えるのは自然なことです。つまり、サーバーは各人の「オフライン・メッセージ・リスト」を保持します。

  • 1)ユーザがオンラインになると、IMS は率先してメッセージを確実に送信し、クライアントから確認応答を受信してから、メッセージがクライアントに到達したとみなし、それに応じてメッセージを「オフライン・メッセージ・リスト」から削除します;
  • (2) クライアントが確認応答を返送しない場合、IM サーバーはメッセージを再送します。

メッセージがクライアントに確実に届くようにするのは論理的なように思えます。当時、市販のIMをいくつか調査しましたが、基本的に動作は同じでした。

オフライン・メッセージの津波

IMオンラインのリファクタリング、内部テスト、およびパブリック・ネットワーク上での実行後、オフライン・メッセージは問題なく動作していました。

その後、プライベート環境は、顧客のために展開され、ユーザーの数は数十万人に達し、組織の1つは3万人に近い、グループ全体も3万人に近いです。

"チェックイン "と "サインイン"。同じようなメッセージの多くは、グループ内の数千、数万人に送信され、誰かが一日か二日のためにオンラインでない場合、またはそれがオンラインになるまで、複数の組織に追加された、一般的な流入の津波のようなオフラインメッセージの数万人は、あなたが想像することができます:携帯電話のユーザーは、数分でログオンし、どのようなシーンですか?

クライアントは、大規模なオフラインメッセージで砲撃されるわけにはいかないので、どうしますか?

プログラムの一時使用

  • 1) フルグループを持つ複数の大規模組織で、管理者以外のユーザーを使用禁止にします;
  • 2) 大きなグループにサインインしないよう、すべてのユーザーに通知します。

正直言って、これは深刻なプログラムではありません。

完全なオフラインメッセージングから離れる

正直言って、オフラインメッセージングの設計を始めた当初は、これがシナリオの用途だとは思っていませんでした。ほとんどのIM開発者にとって、おそらくこのシナリオに出くわすことはないでしょう。

必要不可欠な機能としてのオフライン・メッセージングを放棄

私のこれまでの考え方は、「ユーザが受け取るべきメッセージをすべてクライアントに送信すること」が必 須のメッセージです。

  • 1) ユーザーが新しいメッセージを受け取ったことを認識できるようにすること;
  • 2) ユーザーがそれらのメッセージを見たいときに、1つも見逃すことなく見ることができるようにすること。
  • 1) 顧客があなたにお金を渡したいとき、あなたの家にお金を届ける必要はありません;
  • 2) 代わりに、お金はあなたの銀行口座に振り込まれ、あなたに通知されます;
  • 3) お金を使いたいときは、あなたの銀行口座から直接使ってください。

3) お金を使いたくなったら、銀行口座から直接使えばよいのです。これ以降、オンライン時に大量のオフライン・メッセージがユーザーに送られることはありません。

メッセージが到達しなければならない根拠としてのセッションリスト

クライアントがオンラインになると、まずサーバーからセッションリストを更新します。

{

// 例: プライベートチャット、グループチャット、システム通知、ビジネス通知。

uint32 session_role;

// セッションオブジェクトの ID

uint32 session_id;

// uint32 session_role; // セッションのタイムスタンプ;

// セッションの最後のメッセージの時刻と同じとは限りません。

uint64 session_timestamp; // true は追加または更新を意味します。

// trueは新規または更新、falseは削除を意味します。

boolis_add.

// is_add=falseの場合、以下の情報は無視されます。

// コーナーマーカーの未読数を表示するためにのみ使用され、ユーザがセッションを表示するとクリアされます。

uint32 new_msg_count; // セッションの最後のメッセージ。

// セッションの最後のメッセージ

MessageItem latest_msg; // ジャンプメッセージのタイムスタンプ。

// ジャンプメッセージのタイムスタンプ、つまり new_msg_count の中で最も古いメッセージの時刻。

uint64 goto_timestamp; // ジャンプメッセージのタイムスタンプ。

}

  • 1) 金曜日の夕方18:00に仕事を終えてアプリを閉じると、私は9527です;
  • 2) 1人の若い女性が週末にビーチに行かないかというメッセージを5通送ってきました;
  • 3)その後、別の1人の女性も33通のメッセージを送ってきましたが、その内容は公表できません;
  • 4)厳粛な声明:私は彼女たちにとても無邪気で、実は6379が好きです。

ええ、仮定の話ですから、少しくらいフェイクを入れても問題ありません。

仕事から帰ってきて、携帯に通知バーのメッセージが表示されます。

ログイン後、アプリはパラメータlatest_session_timeに18:00を入力し、IMSからセッションのリストを取得します。IMSのバックエンドがチェックし、私が18:00以降に2つのセッションを更新していることを見つけると、アプリにインクリメンタル形式で2つのセッションエントリを運ぶ回答を送信します:yangmu3306、jingtian5672:

{

uint32 session_role = Role_User; // プライベートチャットであることを示します。

uint32 session_id = 5672; //JingtianのID

uint64 session_timestamp = 1594464295335672; //最後のメッセージのタイムスタンプ(マイクロ秒単位

boolis_add = true; //trueは更新アイテムであることを意味します。

uint32 new_msg_count = 33; //景天は私に33通のメッセージを送っています。

uint64 goto_timestamp = 1594463697556677; // 私に送られた33通のメッセージのうち、最も古いメッセージの時間

}

アプリはステップ2の答えを受信し、アプリのセッションリストウィンドウで2つの更新を見ることができます:
Jingtianのセッション5672をタップすると、アプリはIMSにメッセージを同期するリクエストを開始し、最新の10件のチャットメッセージを取得します:

{

uint32 session_role = Role_User; // プライベートチャットであることを示します。

uint32 session_id = 5672; // JingtianのID

uint64 begin_time = 1594464295335672; //ステップ2で返されたセッションタイムスタンプ

uint64 end_time = 1594434153444222; //JingTianが午前中に最後に送信したメッセージの時刻

uint32 max_pieces = 10; //今回は10個まで、PCの画面が大きい場合は20個まで。

}

IMバックエンドはステップ4のリクエストを受信し、33件の新着メッセージのうち最後の10件をアプリに返します:
また、"↑ 33 new messages "をクリックすると、33件のメッセージのうち最も古いメッセージに直接ジャンプすることができます。

クライアントがサーバーからのオフライン通知を単に受動的に受け取る方法と比べると、このデザインはクライアントの処理ロジックをより複雑にしています。

  • 1) クライアントがサーバからフェッチする同期メッセージは必ずしも完全ではなく、クライアント上に存在するこれらのメッセージは、時間間隔で連続しているとは限りません;
  • 2) クライアントは、異なるメッセージの間に断絶があるかどうかを知る必要があり、断絶がある場合は、ローカル情報をマージして連続的なものにするために、同期メッセージをサーバーに照会る必要があります。

C++で統一されたimsdkライブラリを実装し、これらの共通のメッセージ処理と保存を行います。各クライアントがこれらのロジックを個別に実装するのを避けることで、作業負荷が軽減され、また各エンドでの不整合のリスクも軽減されます。

セッション・リスト・ベースと完全オフライン・メッセージング・シナリオの比較

IMサーバーはメッセージがクライアントに配信されたことを確認し、クライアントはそれを保存して確認のために送り返します。

単純なロジック。

チャット・メッセージの桁が異なる場合のパフォーマンス:

  • a. 少量のオフラインメッセージ:効率性の問題はなく、すべてのメッセージがクライアントにローカルに届くため、ルックアップなどのアクションを実行しやすくなります。
  • b. 膨大な量のオフライン・メッセージ:ユーザがログインする瞬間のCS間の瞬間的なトラフィックが大きく、クライアントは膨大な量のデータを瞬時に保存・更新する必要があり、遅延や偽死などが発生する可能性があります。

クライアントが最初にセッションリストを同期し、ユーザーが時々同期メッセージを駆動します。

ロジックは複雑で、クライアントは多くの作業を追加します。

チャットメッセージのオーダーの違いによるパフォーマンス

  • a. 少量のオフラインメッセージ: 利点なし。
  • b. 膨大な量のオフラインメッセージ:ログイン時のインタラクティブデータが小さく、IMバックエンド、クライアント、ユーザーエクスペリエンスに優しい。

、複数端末がある場合、どのように完全なメッセージ履歴を取得しますか?

同じユーザーの各端末は、そのセッションの最終更新時刻と各セッションの最終入力時刻が異なる可能性があるため、前節の実装アイデアを参照して、解決策を得ることができます。

  • 1)セクション6.2の「アプリとIMバックエンド間のインタラクション」の最初のステップを参照し、異なる増分変更を持つセッションのリストを取得します;
  • (2)セクション6.2の「アプリとIMバックエンド間のやりとり」のステップ4を参照し、任意の間隔の同期メッセージを取得し、完全なメッセージを取得することができます。

オフラインメッセージは完全に非推奨ですか?

配信を確実にするためにオフラインメッセージを保持する必要があるケースがいくつかあります。

  • 1) 他の誰かがオフラインのファイルを送ってきた:この場合、同期メッセージに頼ることはできません。オフラインメッセージの通知がないと、ユーザーは対応するシンクメッセージを引き出すまでオフラインファイルがあることを知らないからです;
  • 2) メッセージの引き出し:受信者がシンクを引き出さない場合でも、ライブ開始後最初にデータが引き出されるようにする必要があります。注意:ここでマルチエンドの引き出しの問題が発生する可能性があります;
  • (3)ユーザーがオンラインである場合のメッセージ送信:ユーザーがオンラインであるため、クライアントにメッセージを送信するIMバックエンドは、メッセージ送信の失敗の結果、ネットワークジッタやその他の条件に遭遇する可能性があり、これらのメッセージは、最初にオフラインメッセージキューに直接格納することができ、IMバックエンドは、メッセージを再送信するクライアントのパケットのハートビートで受信することができます。これは、オンラインメッセージのオフラインキューを維持することと同じです。

(ΦωΦ)フフフ.......................

かつて私の前に誠実な愛があった、時間が半年前に巻き戻した場合、私は、おそらく自分自身で書かれた物語のスクリプトを、メッセージを送信するために信頼性の高いIMを選択する - 美女を保持するの種類の全体のバージョンに時計を戻すかどうか?

No, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no.あなたのことはよく知ってるわ。

Read next

フロントエンドMQTTプロトコル

フロントエンドの多くは、このことについて話すとき、とても混乱するかもしれません。私が触ったこともないこれは何?実際には、これはモノのインターネットのためのプロトコルであり、唯一のモノのインターネットプロジェクトに連絡することができるかもしれませんし、最も完全なまたは公式ドキュメント上の多くの情報ではなく、以下のそれの特徴に公式の導入を行う 実際には、プロジェクトのために。

Sep 30, 2020 · 4 min read

二分探索のまとめ

Sep 30, 2020 · 3 min read

おなじみのフレーバー、FToast

Sep 29, 2020 · 6 min read