かにすることができますので、応答時間の遅延)のクライアントにNodeJSとソケット(ソケットが開かれます。io)?
質問
私が作り出してしまおうというものは、マルチプレイゲームNodeJSたいへの同期をとります。
池尾:そういうふうに考えていうの遅延(依頼時には、クライアント)との間でクライアントとサーバー?
私の最初のアイデアライアント#1が送信タイムスタンプで請求する場合、お客様#2の行動のクライアントの#1彼は調整は動作速度の遅延になります。しかし、問題はそのシステム日付時間のお客様は同一であることはできませんつかのリールの遅延を要求クライアント#1.
のその他のソリューションを使用したタイムスタンプのサーバーからどのようになりますか?待ち時間のクライアント?
解決
思想のご利用はWebSockets ソケットが開かれます。IO しておりますので実施のゲーム遅延に関する事項に関するだタグが付いて).
ってると思い、サーバべきなの測定-追跡すけております。
だめかpingアクセスにはログインサーバを請求することができ、クライアントのどのお客様の要求を送信するレスポンスを返します。サーバがその分割による2更新の遅延する。だサーバーにこれを定期的に各クライアントとその平均の数ように得られないときには、いくつかの奇妙な行動から突然な仮設スパイクです。
それがある場合、メッセージからクライアントのニーズに送信(または放送について他のクライアントの場合、サーバーを追加できclient1の遅延をclient2の遅延を伝えることの遅延のオフセットclient2の一環としてのメッセージ。client2そのことを知らないイベントclient1起こった多くのミリ秒前です。
追加の理由でこのサーバーは一部のブラウザのJavascriptのタイムスタンプは不正確: http://ejohn.org/blog/accuracy-of-javascript-time/.思node.js タイムスタンプを行っているところも正確以上)によV8での正確な。
他のヒント
概要:
socket.io接続が確立された後、新しいものを作成します Date
クライアントのオブジェクト、呼び出しましょう startTime
. 。これはあなたの 初期時間 サーバーにリクエストを行う前に。次に、aを放出します ping
クライアントからのイベント。ネーミングコンベンションは完全にあなた次第です。一方、サーバーはaをリッスンする必要があります ping
イベント、そしてそれが受け取るとき ping
, 、すぐに放出します pong
イベント。その後、クライアントはキャッチします pong
イベント。この時点で、あなたは表す別の日付オブジェクトを作成したい Date.now()
. 。したがって、この時点で、2つの日付オブジェクトがあります - サーバーにリクエストを行う前の初期日付と、サーバーにリクエストを行った後、別の日付オブジェクトが返信しました。減算します startTime
現在から、あなたは持っています latency
.
クライアント
var socket = io.connect('http://localhost');
var startTime;
setInterval(function() {
startTime = Date.now();
socket.emit('ping');
}, 2000);
socket.on('pong', function() {
latency = Date.now() - startTime;
console.log(latency);
});
サーバ
io.sockets.on('connection', function (socket) {
socket.on('ping', function() {
socket.emit('pong');
});
});
aとしても利用できます github gist.
リクエストでタイムスタンプを送信するために私が通常すること:
- クライアントに、aを作成します
new Date()
そして送信しますtimestamp: date.getTime()
すべてのJSONリクエストでサーバーに。 - サーバー上で、リクエストを受信すると、
processed: (new Date()).getTime()
オブジェクト内。 - リクエストを処理します。
- 応答について、
timestamp
リクエストから、および新しい処理されたフィールドから:processed: (new Date()).getTime() - req.processed
これには、リクエストの処理にかかったミリ秒数が含まれています。 - クライアントで、応答を受信するとき、
timestamp
(これはPT 1で送信されたものと同じ)、現在の時刻からそれを減算し、処理時間を差し引く(processed
)、そしてミリ秒単位であなたの「本当の」ping時間があります。
一方向通信がある場合でも、ping時間にリクエストと応答の両方の時間を常に含めるべきだと思います。これは、「Ping Time」と「Latency」の背後にある標準的な意味であるためです。そして、それが一方向通信であり、レイテンシが実際のping時間の半分に過ぎない場合、それは単なる「良いこと」です。
これらすべての答えを読んだ後...
...私はまだ満足していませんでした。私は公式のドキュメントを訪問しました。まあ、まあ、ソリューションはすでに組み込まれています。
あなたはそれを実装する必要があります - 私のものをチェックしてください:
クライアント
// (Connect to socket).
var latency = 0;
socket.on('pong', function(ms) {
latency = ms;
console.log(latency);
});
// Do cool things, knowing the latency...
サーバ
var server = require('http').Server(app);
// "socket.io": "^1.7.1"
// Set pingInterval to whatever you want - 'pong' gets emitted for you!
var io = require('socket.io')(server, {pingInterval: 5000});
私の本当に迅速で汚いスクリプトをテストするために私の本当に迅速で汚いスクリプト... http:// yourserver:8080 ブラウザで、コンソール(私のためのSSHターミナル)を視聴してください。
var http = require('http');
var io = require('socket.io');
server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html>\n');
res.write(' <head>\n');
res.write(' <title>Node Ping</title>\n');
res.write(' <script src="/socket.io/socket.io.js"></script>\n');
res.write(' <script>\n');
res.write(' var socket = new io.Socket();\n');
res.write(' socket.on("connect",function(){ });\n');
res.write(' socket.on("message",function(){ socket.send(1); });\n');
res.write(' socket.connect();\n');
res.write(' </script>\n');
res.write(' </head>\n');
res.write(' <body>\n');
res.write(' <h1>Node Ping</h1>\n');
res.write(' </body>\n');
res.write('</html>\n');
res.end();
});
server.listen(8080);
console.log('Server running at http://127.0.0.1:8080/');
var socket = io.listen(server);
socket.on('connection',function(client){
var start = new Date().getTime();
client.send(1);
client.on('message',function(message){ client.send(1); console.log( new Date$
client.on('disconnect',function(){});
});
カリフォルニアとニュージャージー州の両方で専用のリソースを備えた大きなVPSボックスで、私のpingがかなり高い(200〜400msの往復)ように思えるので、私はこれに非常に興味があります。 (私は東海岸にいます)VPSボックスb/cには、彼らがとても多くのトラフィックを提供しているのに、たったたくさんの待ち時間があると確信していますか?
私を手に入れるのは、同じクライアントから同じサーバーへのLinux端子から通常のpingが平均11msであるということです...私は何か間違ったことをしているのか、node.js/socketで何か遅いことをしていますか。 IO/WebSockets?
最初に読む - なぜこれが機能するはずなのか繰り返し質問があるため、少し明確にしてください。
- クライアントコールバック関数はです クライアントで実行された、 それが、閉鎖にアクセスできる理由です。
start
タイムスタンプを含む変数。これは socket.ioのack()引数。 - サーバーは当然、クライアントの任意の関数を呼び出して、関数の閉鎖にアクセスすることはできません。だが
socket.io
コールバックファンティオンを定義できます 実行されているように見えます サーバーによってですが、これは実際には関数の引数をWebソケットに渡すだけで、クライアントはコールバックを呼び出します。
以下で何が起こるか(サンプルコードを確認してください!):
- クライアントは現在のタイムスタンプを保存します
1453213686429
のstart
- クライアントはaを送信します
ping
サーバーへのイベントと答えを待っています - サーバーは、「空の引数でコールバックに電話してください」でPingイベントに応答します。
- クライアントは応答を受け取り、電話をかけます
clientCallback
空の引数があります(引数を見たい場合はデモコードを確認してください) clientCallback
再び現在のタイムスタンプを取ります クライアントについて, 、例:1453213686449
, 、そしてそれを知っています20 ms
リクエストを送信してから合格しました。
ドルイドを想像してください (クライアント) メッセンジャーのときにストップウォッチを持ってボタンを押す (イベント) 走り始め、メッセンジャーが巻物で到着したときに再びそれを押します (関数引数). 。次に、ドルイドは巻物を読み取り、ポーションレシピに成分名を追加し、ポーションを醸造します。 (折り返し電話)
さて、前の段落を忘れてください、私はあなたがポイントを得たと思います。
質問はすでに回答されていますが、ここではRTTをチェックするための短い実装があります socket.io
:
クライアント
var start = Date.now();
this.socket.emit( 'ping', function clientCallback() {
console.log( 'Websocket RTT: ' + (Date.now() - start) + ' ms' );
} );
サーバ
socket.on( 'ping', function ( fn ) {
fn(); // Simply execute the callback on the client
} );
デモコード
ノードモジュールとしてのデモコード: socketio-callback.tgz セットアップして実行します
npm install
node callback.js
そして、にナビゲートします http:// localhost:5060