Javascript Socket.io未发出超过1个事件

Javascript Socket.io未发出超过1个事件,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,因此,我在node.js中获得了一个应用程序来读取CSGO演示,它解析文件,我想在每次更新实体时向客户端发送一个带有socket.io的事件。 它可以工作,但是它只触发“client.emit('tick','a');”但是console.log会正确地触发,任何人都可以帮我找出socket.io阻止发射的原因 服务器代码 var server = require('http').createServer(); var io = require('socket.io')(server); var

因此,我在node.js中获得了一个应用程序来读取CSGO演示,它解析文件,我想在每次更新实体时向客户端发送一个带有socket.io的事件。 它可以工作,但是它只触发“client.emit('tick','a');”但是console.log会正确地触发,任何人都可以帮我找出socket.io阻止发射的原因

服务器代码

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

您必须将套接字保存在某些存储器中,以便在每次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);

通过使用您提供的文件(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..循环可以复制相同的内容。检查以下代码:

 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');  
 }
for循环结束后,socket/io层通过socket写入数据。一旦demo.parse()完成处理,代码也会发生同样的情况


您必须找到一种从jsgo获取数据的替代方法,以便取消阻止事件循环并将其提供给socket.io。也许你可以在jsgo github上提出一个增强请求。

已经尝试过了,但还是一样,它只发出第一个“勾号”,你的代码在我看来是正确的。您确定已多次调用“实体_updated”吗?你能分享你的“train.dem”吗?这样我就可以在我的末尾检查它了?它会触发console.log,所以会被调用,这是dem的链接。你能给我举个例子,说明如何在没有for循环的情况下读取文件吗?如果我创建一个流,并像“readStream.on('data',function(chunk)”那样使用它它会起作用吗?问题不在于读取文件,而在于jsgo解析代码。它调用的“emit”太多了。如果它可以在下一次勾选时使用setimmediate或其他方法调用这些emit,它可能会起作用。此外,我不知道jsgo是否可以接受文件块。如果可以,那么这也是一种方法。
 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