ブラウザーのMail.Ruエージェント:状態の同期化のアプローチ

現代のインターネットで最も顕著な傾向の1つは、最近までユーザーのコンピューターで最高位だった「クラシック」デスクトップメッセンジャーの役​​割の弱体化と、モバイルおよびWebクライアントの役割の増大です。 後者は、新世代の電子メールサービスとソーシャルネットワークのおかげで特に人気を集めています。



Mail.Ruは、2008年にMail.Ru Agent for the Webの最初のバージョン(以下、単にAgentと呼びます)を立ち上げました。









ただし、ユーザーがスタンドアロンアプリケーションとWebクライアントの違いについて考えることさえできない場合、その違いは開発者には明らかです。 ただし、ブラウザと対話するために別のプログラムの哲学を変更することによって解決しなければならない困難と問題は、あまり透明ではありません。



この場合の開発者の最初の「敵」...ユーザー自身。 ソーシャルネットワークやメールページで友人と話すことに集中する代わりに、彼はリンクをクリックしてページを調べます。 だから-あなたは、クライアントの完全な状態を覚えて、次のロードされたページでそれを復元する必要があります。



そして、この問題が解決するとすぐに、ユーザーはブラウザがタブをサポートしていることを覚えており、たとえば新しいタブで文字を開き始めます。 この場合、ユーザーがクライアントの開いているすべてのコピーと現在対話しているクライアントの状態を同期する必要があります。これにより、クライアントはどのタブでも同じように見えます。



一般に、開発者は、クライアントの状態を保存/変更および同期するという問題に直面しています。



エージェントの開発履歴は、上記の問題を克服する開発者の歴史とほぼ一致しています。 その過程で、私たちは、克服または回避しなければならない多くの予想される予期しない困難に遭遇しました。 これが実際にどのように見えるかを一般的な用語で説明しようとします。



ただし、最初に作業グループでよく使用する基本概念を決定します。 この記事を理解するには、 状態イベントルーター、 クライアントの 4つの用語だけを覚えておけば十分です



状態は、現在の外観(プレゼンテーション)を決定するエージェントプロパティのセットです。 このようなプロパティには、開いているダイアログのリスト、現在のダイアログの兆候、開いているダイアログ内の未読メッセージの存在、エージェントの擬似ウィンドウのステータス(最小化/最大化)、通知の入力などが含まれます。



状態は、状態の正確な変化に関する情報を含むイベントによって変更できます。 イベントは、サーバー(たとえば、誰かがユーザーにメッセージを書き込んだとき)またはクライアントによってトリガーできます。



クライアントは、ユーザーのブラウザーで実行され、状態に応じてユーザーインターフェイスを表示するプログラムです。 さらに、クライアントはイベントを生成できます。たとえば、ユーザーがダイアログを開いたり閉じたり、擬似ウィンドウを展開または折りたたんだときです。



最後に、 ルーターは、すべてのクライアントが接続し、常に最後のエージェントの状態を「認識」する一種の「ブラックボックス」です。 ルーターの主なタスクは、サーバーと、ユーザーが現在対話しているクライアントからイベントを受信し、接続されている他のクライアントに送信することです。 したがって、ルーターはクライアントのすべてのコピー間で状態の同期を提供します。



NB:一般に、ネットワーク用語の観点からは、ルーターをハブと呼ぶ方がより適切ですが、歴史的に発展しています。 :)



ステージング。 サーバーの同期。



最初に試みた解決策はサーバーの同期でした。つまり、「実際の」専用サーバーがルーターとして機能していました。 利点は明らかであるように見えます。接続しているブラウザまたはコンピューターに関係なく、すべてのクライアントのステータスが同期されます。 クライアントの設計のシンプルさも非常に魅力的でした。そのタスクはユーザーとの対話と状態の変化のレンダリングのみであったため、本当に「薄い」ことが判明しました。



ただし、ほとんどすぐに2つのボトルネックが現れました。



その結果、エージェントは多かれ少なかれ、高速ネットワーク接続上の1つまたは2つのダイアログでのみチャットを処理し、中程度のユーザーアクティビティの影響を受けていました。 ユーザーが多数の連絡先との通信を開始し、すぐに通信を開始するとすぐに、ネットワークオーバーヘッドの負荷の下で、特に多数の開いているウィンドウで同期が「崩壊」しました。結局、各ウィンドウに同じイベントを個別に配信する必要がありました。 応答速度が遅いことに加えて、このアプローチではルーターに高い負荷がかかるため、すぐに破棄しました。



IIステージ。 同期をクライアントに転送します。



サーバー同期の質問に対する明白な答えは、このタスクをクライアントコンピューターに転送することでした。 ここに、他のユーザーと共有されない計算能力と、システム「browser1-server-browser2」に固有の長い「肩」の欠如があります。



ソリューションとして、Adobe Flashが選択されました。イベントディスパッチ専用に設計されたFlash Local Connectionクラスが選択されました。 このアーキテクチャでは、最初に実行されているクライアントインスタンスはルーターでした。 クライアントは、新しいコピーごとに、ルーターが既に作成され、接続され、サーバーから直接ではなく、ルーターから状態の送受信を開始したかどうかを確認しました。 本質的に、それは「厚い要素を持つシンクライアント」であることが判明しました。 :)



この実装により、サーバーの同期に比べて軽減されましたが、すぐに他の問題に遭遇しました。今回は、残念ながら、Flash Player自体に「埋もれて」しまいました。



そもそも、Flash Playerの内部ストレージでは、データの書き込みと読み取り、および大量のデータの保存ができないことがよくあります。これは、エージェントを集中的に使用する場合の一般的なシナリオです。



ただし、最大の問題は、Flash Playerの次の更新後に始まりました。理由は不明ですが、ローカル接続の接続速度が急激に低下し、1つのタブから別のタブへの信号が文字通り「ワイヤーで迷子になり」ました。 それほど高速ではないFlash Playerの全体的なパフォーマンスと組み合わせることで、これは多くの場合、大幅な同期外れにつながりました。



IIIステージ。 HTML 5を使用したクライアントの同期。



HTML 5のリリースと最新のほとんどのブラウザでのサポートの実装により、Webアプリケーション開発者に新しいツールが提供されました。 私たちにとって最高のニュースは、独自のローカルブラウザストレージが登場したことです。 現在、外部テクノロジを使用せずに、約5 MBのデータをローカルに保存し、各クライアントインスタンスにすばやくアクセスできるようになりました。 実際、これは同じローカル接続であり、読み取りと書き込みの制限がないだけでなく、はるかに高速で信頼性が高いだけです。



実際には、これにより、ルーターを放棄して、すべてのクライアントインスタンスが「参照」し、簡単に変更できる一般的な状態を保存できます(もちろん、これは1つのブラウザー内でのみ機能します)。 しかし、新たな機会とともに、新たな困難が生じました。 たとえば、ページをエージェントとホストする異なるドメイン間で状態を同期するために、同じオリジンポリシーの対象となるiframeが作成されます。 この制限を回避するには、 EasyXDMライブラリーとpostMessageトランスポートを使用する必要がありました。 興味深いことに、このライブラリは、送信者と受信者の検証を伴うクロスドメインメッセージ交換の可能性を提供します。



現在、この同期方法が主な方法ですが、ローカルストレージをサポートしない古いブラウザーでは、Flash Playerを介した状態の同期を使用する必要があります。



そして最後に、私は言います...



現時点でのWebエージェントの外観は、美しいものに関するアイデアとはまったく一致していませんが、積極的に取り組んでおり、まもなく新しいデザインを公式に発表する準備が整います。 発表を待ってください!



イリヤ・ナウモフ、

プロジェクトマネージャーMail.Ruエージェント



All Articles