2017-02-25 13 views
1

私はnode.jsにCSGOデモを読むためのアプリケーションを持っていて、ファイルを解析して、エンティティが存在するたびにsocket.ioでイベントをクライアントに出したいと思っていました。更新しました。 これはうまく動作しますが、 "client.emit( 'tick'、 'a');しかし、console.logが確実に発生すると、誰も私がsocket.ioがなぜemitを妨げているのかを知るのを助けることができますか?あなたはenitityが更新されるたびに放出するために、いくつかのストレージにソケットを保存する必要がSocket.ioは1つ以上のイベントを出力しません

サーバコード

var server = require('http').createServer(); 
var io = require('socket.io')(server); 
var fs = require('fs'); 
var jsgo = require('jsgo'); 
io.on('connection', function(client){ 
    fs.readFile('train.dem', function (err, data) { 
     var demo = new jsgo.Demo(); 
     demo.on('entity_updated', function (entity) { 
      console.log('entity_updated'); 
      client.emit('tick', 'a'); 
     }); 
     demo.parse(data); 
    }); 
}); 
server.listen(3000); 

クライアントコード

var socket = io('http://localhost:3000'); 
socket.on('connect', function() { 
    console.log('connected'); 
}); 
socket.on('tick', function (data) { 
    console.log('entity_updated'); 
}); 
socket.on('disconnect', function() { 
    console.log('disconnect'); 
}); 
+0

あなたのコードは私に似ています。 'entity_updated'が複数回呼び出されていますか?あなたの 'train.dem'を共有して、私が最後に確認できるようにすることはできますか? – manishg

+0

これはconsole.logをトリガーしているので、ここではdemのリンクです https://www.4shared.com/file/GIUeIS3jba/train.html –

答えて

1

提供したファイル(train.dem)を使用してこの問題を再現できました。 socket.ioが複数のメッセージを送信することができない理由理由は、このステートメントにある:

demo.parse(data); 

のNode.jsはシングルスレッド環境であり、上記のステートメントは、イベントループをブロックしています。私は上記のステートメントを実行すると、それは永遠に完了しています。私はコードを15分以上走らせましたが、この処理は処理の量が多すぎるために終了しませんでした。イベント駆動のシングルスレッド環境のため、ノードはメッセージを送信できません。すべてのメッセージがバッファリングされ、このループが終了するのを待っています。

私はあなたのコードにいくつかのより多くのログを追加し、あなたが書き込み可能フラグを観察することができます:同じfor..loopを使用して再現することができ

socket.io:server initializing namespace/+0ms 
    socket.io:server creating engine.io instance with opts {"path":"/socket.io"} +5ms 
    socket.io:server attaching client serving req handler +4ms 
    engine:socket sending packet "open" ({"sid":"SFD8FKG2G_MjW78SAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}) +0ms 
    engine:socket flushing buffer to transport +2ms 
    engine:socket executing batch send callback +6ms 
    socket.io:server incoming connection with id SFD8FKG2G_MjW78SAAAA +7s 
    engine:socket sending packet "message" (0) +5ms 
new client 
    engine:socket might upgrade socket transport from "polling" to "websocket" +36ms 
    engine:socket flushing buffer to transport +2ms 
    engine:socket executing batch send callback +5ms 
    engine:ws received "2probe" +15ms 
    engine:ws writing "3probe" +2ms 
readFile done null 
started 
server --> entity_updated for 1client.conn.transport.writable true 
    engine:socket sending packet "message" (2["tick","a"]) +258ms 
    engine:socket flushing buffer to transport +1ms 
server --> entity_updated for 2client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +2ms 
server --> entity_updated for 3client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +1ms 
server --> entity_updated for 4client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 5client.conn.transport.writable false 

を。ループが終了するため、ソケット/ IO層はソケット経由でデータを書き込み、いったん

socket.io:server initializing namespace/+0ms 
    socket.io:server creating engine.io instance with opts {"path":"/socket.io"} +7ms 
    socket.io:server attaching client serving req handler +3ms 
    engine:socket sending packet "open" ({"sid":"b86YJD0sGGawVZseAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}) +0ms 
    engine:socket flushing buffer to transport +2ms 
    engine:socket executing batch send callback +6ms 
    socket.io:server incoming connection with id b86YJD0sGGawVZseAAAA +2s 
    engine:socket sending packet "message" (0) +6ms 
new client 
    engine:socket might upgrade socket transport from "polling" to "websocket" +23ms 
    engine:socket flushing buffer to transport +4ms 
    engine:socket executing batch send callback +2ms 
    engine:ws received "2probe" +8ms 
    engine:ws writing "3probe" +5ms 
readFile done null 
started 
ended 
server --> entity_updated for 1client.conn.transport.writable true 
server --> entity_updated for 1client.conn.transport.writable true 
    engine:socket sending packet "message" (2["tick","a"]) +100ms 
    engine:socket flushing buffer to transport +0ms 
server --> entity_updated for 2client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +1ms 
server --> entity_updated for 3client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 4client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 5client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 6client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +1ms 
server --> entity_updated for 7client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 8client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 9client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
server --> entity_updated for 10client.conn.transport.writable false 
    engine:socket sending packet "message" (2["tick","a"]) +0ms 
    engine:ws received "5" +3ms 
    engine:socket got upgrade packet - upgrading +0ms 
    engine:socket flushing buffer to transport +1ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +1ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +0ms 
    engine:ws writing "42["tick","a"]" +1ms 
    engine:ws writing "42["tick","a"]" +1ms 
    engine:socket executing batch send callback +0ms 

for (i=0; i<10; i++) 
{ 
    console.log('server --> entity_updated for ' + count + 'client.conn.transport.writable ' + client.conn.transport.writable); 
    count++; 
    client.emit('tick', 'a'); 
} 

と以下のログ:以下のコードを確認してください。 demo.parse()が処理を完了した後も同じことがコードに発生します。

イベントループのブロックを解除してsocket.ioに送るために、jsgoからデータを取得する別の方法を見つけなければなりません。 jsgo githubでエンハンストリクエストを行うことができます。

+0

for-loopなしでファイルを読み込む方法の例を教えてください。 ストリームを作成し、 "readStream.on( 'data'、function(chunk))のように使用するとエラーが発生しますか? –

+0

問題はファイルを読み込むことではなく、jsgoの解析コードにあります。 setimmediateやその他の方法で次のティックでこれらのエミットを呼び出すことができるなら、jsgoがファイルチャンクを受け入れることができるかどうかわかりません。 – manishg

0

今のところ、変数に接続するとソケットを保存しようとすることができますが、新しいソケットが接続されるたびに新しいソケットIDで更新されるため、多くのクライアントでこの機能は動作しません。

var server = require('http').createServer(); 
    var io = require('socket.io')(server); 
    var fs = require('fs'); 
    var jsgo = require('jsgo'); 
    var socketId; // this will only store one id. store it in some data storage or create room for each user and emit in room 
    io.on('connection', function(client){ 
     socketId = client.id; 
     fs.readFile('train.dem', function (err, data) { 
      var demo = new jsgo.Demo(); 
      demo.on('entity_updated', function (entity) { 
       console.log('entity_updated'); 
       if(io.sockets.connected[socketId]) //check if socket is still connected. 
       { 
        io.sockets.to(socket.socketId).emit('tick', 'a'); 
       } 

      }); 
      demo.parse(data); 
     }); 
    }); 
    server.listen(3000); 
+0

既に試したことがあります最初の 'tick'を出す –

関連する問題