2017-02-25 44 views
1

因此,我在node.js中读取了一个应用程序来阅读CSGO演示程序,它解析了该文件,并且我希望每当实体发生事件时都向客户端发送带有socket.io的事件更新。 它可以工作,但它只会触发“client.emit('tick','a');”但console.log正确地触发,任何人都可以帮我找出为什么socket.io防止发射?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分钟的代码,但这个函数并未退出,可能是由于它正在处理的数量。由于事件驱动的单线程环境,节点无法发送消息。所有的消息都被缓冲并等待这个循环退出。

我加了些木柴到你的代码,你可以观察到可写的标志:

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 

同样可以使用for..loop重现。检查以下的代码:

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'); 
} 

和下面的日志:

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循环结束时,插座/ IO层上插座写入数据。一旦demo.parse()完成处理,代码也会发生同样的情况。

您将不得不找出从jsgo获取数据的另一种方法,以便取消阻塞事件循环并将其提供给socket.io。可能你可以在jsgo github上提出增强请求。

+0

你能给我一个例子,关于如何在没有for循环的情况下读取文件吗? 如果我创建一个流,并使用它像“readStream.on('data',function(chunk)”它会工作吗? –

+0

问题不在于读取文件,而是在jsgo解析代码中。如果它可以使用setimmediate或其他方式调用它们,那么它也可以工作,并且我不知道jsgo是否可以接受文件块,如果可以,那也是一种方法。 – manishg

0

你必须保存插座一些存储发出每enitity更新时间。

现在你可以尝试在变量中连接时保存套接字,但这不适用于许多客户端,因为每次新套接字连接变量时都会用新套接字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

试过了,它仍然是一样的,它只发出第一个'嘀嗒' –