9

私は現在、サーバーとすべてのクライアント間で適切な時刻同期を本質的に必要とするアプリケーションを構築しようとしています。この同期の必要性をなくすことができる私のアプリケーション用の代替設計がありますが、私のアプリケーションは同期が存在しないとすぐに機能しなくなります。

何か不足している場合に備えて、私の基本的な問題は次のとおりです。複数の場所でまったく同時にイベントを発生させます。私が知る限り、これを行う唯一の方法はある種の時刻同期を必要としますが、私は間違っているかもしれません。問題を別の方法でモデル化しようとしましたが、すべて a) つまらないアプリ、または b) 時刻同期が必要です。

同期された時間が本当に本当に必要だと仮定しましょう。

私のアプリケーションは Google AppEngine で構築されています。AppEngine はサーバー間での時刻同期の状態について保証しませんが、通常は数秒程度 (つまり NTP よりも優れている) で非常に良好ですが、10 秒程度遅れる場合もあります。同期の。私のアプリケーションは 2 ~ 3 秒の同期のずれを処理できますが、ユーザー エクスペリエンスに関しては 10 秒は問題外です。基本的に、私が選択したサーバー プラットフォームは、信頼できる時間の概念を提供しません。

私のアプリケーションのクライアント部分は JavaScript で書かれています。ここでもまた、クライアントが信頼できる時間の概念を持っていない状況があります。私は測定を行っていませんが、私の最終的なユーザーの何人かは、1901 年、1970 年、2024 年などに設定されたコンピューターの時計を持っていることを完全に期待しています。基本的に、私のクライアント プラットフォームは信頼できる時間の概念を提供しません。

この問題は私を少し怒らせ始めています。これまでのところ、HTTP の上に NTP のようなものを実装するのが最善だと思います (これは思ったほどクレイジーではありません)。これは、インターネットのさまざまな場所に 2 つまたは 3 つのサーバーを設置し、従来の手段 (PTP、NTP) を使用して同期が少なくとも数百ミリ秒のオーダーであることを確認することで機能します。

次に、これらの HTTP 時刻ソース (および XMLHTTPRequest から入手できる関連するラウンドトリップ情報) を使用して、NTP 交差アルゴリズムを実装する JavaScript クラスを作成します。

お分かりのように、このソリューションも非常に時間がかかります。それは恐ろしく複雑であるだけでなく、問題の半分を解決するだけです。つまり、クライアントに現在の時間の適切な概念を与えることです。次に、サーバーで妥協する必要があります。クライアントが要求を行うときに、クライアントがサーバーに応じて現在の時刻を伝えることができるようにする必要があります (大きなセキュリティではありませんが、これのより明白な乱用のいくつかを軽減できます)。または、サーバーが魔法の HTTP-over-NTP サーバーの 1 つに単一の要求を作成し、その要求が十分に迅速に完了することを期待します。

これらの解決策はすべて最悪で、私は道に迷っています。

注意: Web ブラウザーの束 (できれば 100 以上) が、まったく同時にイベントを発生できるようにしたいと考えています。

4

5 に答える 5

3

質問を確実に理解するために、要約させてください。

クライアントとサーバーのコンポーネントを持つアプリがあります。それぞれが多数(数百)のクライアントにサービスを提供できる複数のサーバーがあります。サーバーは多かれ少なかれ相互に同期されています。クライアントはそうではありません。最初に接続したサーバーに関係なく、多数のクライアントがほぼ同時に同じイベントを実行する必要があります。

私が状況を多かれ少なかれ正確に説明したと仮定すると:

サーバーにクライアントごとに特定の状態(接続の初期時刻-サーバー時刻など)を保持させ、発生する必要のあるイベントの時刻がわかったら、ミリ秒数を含むメッセージでクライアントに通知できますか?イベントを発生させる前に経過する必要がある開始値の後?

説明する:

   クライアントAは時間t0=0でサーバーSに接続します
   クライアントBは時間t1=120でサーバーSに接続します
   サーバーSは、イベントが時間t3=500に発生する必要があると判断します。
   サーバーSはAにメッセージを送信します。
   S-> A:{eventName、500}
   サーバーSはBにメッセージを送信します。
   S-> B:{eventName、380}

これは、クライアントの時間にはまったく依存しません。適度に短い期間(単一のセッション)の時間を追跡するクライアントの能力だけです。

于 2009-01-11T07:04:48.777 に答える
2

さまざまな場所にあるサーバーからのブロードキャストイベントを聞く必要があるように思えます。2〜3秒のバリエーションを受け入れることができるので、すべてのクライアントを長寿命のコメットスタイルのリクエストに入れて、サーバーから応答を取得することができますか?クライアントがこのように時間を処理する必要がまったくないように私には聞こえますか?

これを行うにはajaxを使用できるため、新しいデータを待つ間、クライアント側のロックアップを回避できます。

ここで何かが完全に欠けている可能性があります。

于 2009-01-11T06:39:02.450 に答える
1

クロックが適度に安定していると仮定できる場合 - つまり、クロックは間違って設定されていますが、多かれ少なかれ正しいレートで刻んでいます。

サーバーが単一の定義されたソース (たとえば、サーバーの 1 つ、またはデータベース サーバーなど) からオフセットを取得するようにします。

次に、各クライアントにサーバーからのオフセットを計算させます(多くの精度が必要な場合は、往復の複雑さの可能性があります)。

それを保存してから、各クライアントで組み合わせたオフセットを使用して、適切なタイミングでイベントをトリガーします。

(client-time-to-trigger-event) = (scheduled-time) + (client-to-server-difference) + (server-to-reference-difference)
于 2009-01-11T09:09:29.307 に答える
0

時間の同期を正しく行うのは非常に難しく、私の意見では、それを行う方法は間違っています。イベントがディスパッチされるたびに登録済みのオブザーバーに通知できるイベント システムが必要です (オブザーバー パターン)。すべてのオブザーバーに同時に (または可能な限りそれに近いタイミングで) 通知が送信されるため、時刻を同期する必要がなくなります。

待ち時間に対応するには、ブラウザにイベント ディスパッチのタイムスタンプを送信し、予想される最大待ち時間よりも少し長く待機する必要があります。このようにして、すべてのイベントがすべてのブラウザで同時に起動されます。

于 2009-01-11T05:58:22.297 に答える