いくつかのゲーム トンネリング サーバーを実行していますが、クライアントがすべてのサーバーに対して ping を実行し、最も応答性の高いサーバーを見つけられるページが必要です。私が見る限り、JavaScript でこれを行う適切な方法はないようですが、フラッシュまたは他のクライアント ブラウザ テクノロジでこれを行う方法を知っている人はいますか?
9 に答える
Javascript を含むほとんどのアプレット テクノロジでは、同一オリジン ポリシーが適用されます。画像などの DOM 要素を動的に追加し、onload イベント ハンドラを使用してタイミング情報を収集できる場合があります。
疑似コード
for (server in servers) {
var img = document.createElement('IMG');
server.startTime = getCurrentTimeInMS();
img.onload=function() { server.endTime = getcurrentTimeInMS(); }
img.src = server.imgUrl;
}
次に、適切な時間待ってから、各サーバー オブジェクトのタイミングを確認します。必要に応じて繰り返し、必要に応じて平均を計算します。どのような精度が期待できるかはわかりません。
短所:
- あなたはおそらく、仕事に間違ったツールを使用しています。この種のアプリケーションにはブラウザが装備されていません。
- おそらくかなり不正確です。
- リクエストしたリソースがキャッシュされている場合、必要な結果は得られませんが、毎回 URL を変更することで回避できます。
- これは、通常の ping と比較して帯域幅を集中的に使用します。画像は、spacer.gif ファイルのように小さくします。
- タイミングは、リモート サーバーの遅延だけでなく、そのサーバーの帯域幅にも依存します。これは多かれ少なかれ有用な尺度かもしれませんが、単にレイテンシーではないことに注意することが重要です。
- さまざまなサーバーからの HTTP 要求を処理できる必要があり、重要なことに、各サーバーはまったく同じリソース (または同じ長さのリソース) を処理する必要があります。あるサーバーがデータを圧縮しており、別のサーバーは圧縮していない場合など、サーバーの条件が応答時間に影響を与える可能性があります。
サーバーを呼び出す前に、Javascriptの時間を記録します。
var startTime = new Date();
サーバーから画像をロードします。
var img = new Image()
img.onload = function() {
// record end time
}
img.src = "http://server1.domain.com/ping.jpg";
リクエストが終了したらすぐに、時間をもう一度記録します。(もちろん、リクエストがタイムアウトしなかったことを考えると。)
var endTime = new Date();
ミリ秒単位のpingは次のとおりです。
var ping = endTime. getTime() - startTime.getTime();
本当に必要なのは、接続開始から最初の状態変更までの時間です...
関数getPing(){ var start; var client = getClient(); //xmlhttprequestオブジェクト client.onreadystatechange = function(){ if(client.readyState> 0){ pingDone(start); //pingを処理します client.onreadystatechange = null; //ハンドラーを削除します } } start = new Date(); client.open( "HEAD"、 "/ping.txt"); //静的ファイル client.send(); } 関数pingDone(start){ done = new Date(); ms = done.valueOf()-start.valueOf(); alert(ms + "ms ping time"); } 関数getClient(){ if(window.XMLHttpRequest) 新しいXMLHttpRequest();を返します。 if(window.ActiveXObject) 新しいActiveXObject('MSXML2.XMLHTTP.3.0');を返します。 throw( "使用可能なXMLHttpRequestオブジェクトがありません。"); }
<iframe>
アプローチは次のとおりです。
(出典:magnetiq.com)
<table>
2 つの列を持つテーブルを作成します (文字通りの意味である必要はありません)。最初の列には、サーバーの名前 (および場合によってはサーバーへのリンク) が保持されます。2 番目の列には、それぞれのサーバーからプローブ ドキュメントをロードする iframe があります。各プローブ ドキュメントは、最初のフェッチ リクエストでこれを行います。
- 現在のシステム時刻を取得する
- システム時刻をクエリ パラメータとして渡しながら、2 番目のプローブ ドキュメントへのリダイレクト (302) を実行します。
- 2 番目のプローブ ドキュメントは、現在のシステム時間を読み取り、渡された最初の読み取り値からデルタを計算し、それを大きな太字で表示します。このデルタは、サーバーがリダイレクト応答でクライアントに応答するのにかかった時間と、クライアントがリダイレクト ターゲットに 2 番目の要求を行うのにかかった時間です。これは正確には「ping」ではありませんが、各サーバーでのクライアントの相対的な待ち時間の同等の尺度です。実際、これはサーバーからクライアントへの「逆 ping」です。
iframe のコンテンツをまったく操作しようとしないため、同一ドメイン ポリシーに違反することなく iframe を使用できます。プレーヤーは単に自分の目で値を確認するだけなので、ユーザーが数字をちらりと見て、最も理にかなったサーバー リンクをクリックすることに依存します。
HTTP リクエストを行うもの (ここでのほとんどの回答のように) は、通常、通常の ping で見られるものの少なくとも 2 倍のレイテンシを測定します。これは、少なくとも 3 ウェイ ハンドシェイクと終了パケット ( 1往復ではなく2往復)。HTTP 要求を行う場合は、ヘッダーを最小限に抑えるようにしてください。十分な長さのヘッダー (おしゃべりなサーバー、またはクライアントの Cookie などによる) は、追加のラウンドトリップをミックスに追加し、測定値を台無しにする可能性があります。
Cherona が指摘しているように、サーバーへのアクティブな HTTP 2 接続が既にある場合、またはサーバーが HTTP 3 を話す場合、これは当てはまらない可能性があります。
最も正確なオプションは、各サーバーへの websocket 接続を開き、小さなメッセージを送信して小さな応答を受信するのにかかる時間を測定することです (接続が確立された後)。
Flash でサーバーの応答時間を測定することはそれほど難しくありません。
Flash は、リモート サーバーにアクセスする前にポリシー ファイルを要求する必要があります。このようなポリシー ファイルのデフォルトの場所は、サーバーのルート フォルダー /crossdomain.xml です。
(クロスドメイン ファイル形式に関する情報は簡単に見つけることができます)
とにかくそのようなファイルが必要なので、それを使用してサーバーの応答時間を測定してみませんか? 画像の代わりにファイル自体を読み込み、 getTimer() を使用してかかった時間を測定します。
これにより、HTTP 接続の適切な見積もりが得られます。
ただし、ゲーム サーバーを扱っている場合は、TCP 接続の速度を直接確認することをお勧めします。これを行うには、flash.net.Socket を使用する必要があります。また、次のコマンドを実行して、最初にポリシー ファイルを要求する必要もあります。
5342 はサーバーのポート番号を表し、適切な XML ポリシー文字列で応答する必要があります。ソケット接続を確立した後は、要求/応答によって、さまざまなサーバーの応答時間を測定できます。
クライアント側で何かを実行することについて話している場合、セキュリティ上の理由からこれが可能かどうかはわかりません.
最善の策は Java アプレットかもしれませんが、これもローカル セキュリティ ポリシーに照らしてチェックする必要があります。
これを行うためにJSでハックを考えようとすると、コールバック関数を使用して非同期リクエストを送信して、ミリ秒を測定することができるかもしれませんが、これは私の頭の中から外れています。
'file pings'の問題は、httpサーバーの応答を評価するのに対し、提供するゲームのターゲットリソースの動作が大きく異なるため、レイテンシーが異なる可能性があることです。
思いがけないアイデアであり、実際のコンテキストによっては非現実的かもしれません。ただし、ゲームプレイ中にサーバーによって通常実行される一連の短いタスクに基づいてサーバースクリプトを作成するのは興味深いことではありません(RTMPを開くなど)。接続、情報の取得、返送)。サーバーの総数に応じて、サーバーをほぼ同時に開き、最初の応答を勝者として定義できます(クライアントが各クエリを処理するために個別に必要な時間を差し引きます)。
もちろん、これはサーバー側で話すと非常に高価な方法ですが、少なくとも信頼できる結果が得られることを願っています(サーバーとネットワークの遅延を合計したもの)。評価に数秒かかるとしても、これは楽しいゲームプレイ全体のほんの一部の問題です。