BinaryJS WebSockets 泄露内存

3
我正在尝试编写一个简单的客户端/服务器实现,使用BinaryJS websockets在浏览器和node.js服务器之间传输图像数据。

按照api示例,我已经想出了一些看起来可以工作的东西,但是似乎会泄漏内存,因为' top '报告的node进程使用情况不断增加。

我对javascript调试不太熟悉,但是使用nodetime,我发现似乎没有创建的对象被垃圾回收。

我的基本代码如下:

服务器端:

var BinaryServer = require('binaryjs').BinaryServer;
var fs = require('fs');

var server = BinaryServer({port: 9000});

server.on('connection', function(client){
    console.log('Connection');
    client.on('stream', function(stream){
        stream.on('data', function(data) {
            var file = fs.createReadStream(data['path']);
            client.send(file, {'target':data['target']});
        });
    });
});

客户端:

var client = new BinaryClient('ws://example.com:9000');
var controlStream;

function loadImage(target, src) {
  controlStream.write({'path':src, 'target':target});
}

client.on('open', function(){
  controlStream = client.createStream();
});

client.on('stream', function(stream, meta){    
  var parts = [];
  stream.on('data', function(data){
    parts.push(data);
  });

  stream.on('end', function(){
    $('#'+meta['target']+' img').attr('src', (window.URL || window.webkitURL).createObjectURL(new Blob(parts)));
  });
});

我的理解是:客户端打开与服务器的连接,然后创建一个用于发送请求的流。当服务器从此流接收到数据时,它会打开一个请求路径的FileStream,并将数据通过新流传输到客户端。完成后,客户端使用这些数据更新页面元素。
我漏掉了什么吗?
2个回答

1
这是关于 .createReadStream() 的已知问题(嗯,有点吧);基本上,它没有像应该那样自动释放资源。以下是您的脚本的修改版,应该可以解决这个问题:
var BinaryServer = require('binaryjs').BinaryServer;
var fs = require('fs');

var server = BinaryServer({port: 9000});

server.on('connection', function(client){
    console.log('Connection');
    client.on('stream', function(stream){
        var file; //Moved this so it's accessible to the 'end' handler
        stream.on('data', function(data) {
            file = fs.createReadStream(data['path']);
            client.send(file, {'target':data['target']});
        });

        stream.on('end', function(){
            if (file) file.destroy.bind(file); //Releases the handle and allows garbage collection
        });

        client.on('close', function(){
            if (file) file.destroy.bind(file); //Releases the handle and allows garbage collection
        });

    });
});

我不熟悉 binaryjs,但是 @aecend 的答案似乎是合法的。同样适用于JavaScript事件处理程序(每当您看到.on时,请注意您正在销毁它)。 - GuyT
实际上,createReadStream问题不仅影响BinaryJS。这是Node.js本身的问题。当流传输完成时,它应该自动关闭文件句柄并释放内存,但它没有这样做,因此您必须手动关闭它。 - aecend
谢谢!我觉得一定是这样的,我应该多搜索一下。 - so12311
没问题,很高兴能够帮助。 - aecend

0
如果我理解正确的话,您想使用BinaryJS从客户端(浏览器)向服务器发送二进制数据(而不是相反),并使用流。如果是这样的话,那么您提供的代码片段并没有实现您想要的功能。
您能告诉我们更多信息吗?

不,我想把数据从服务器传输到浏览器。 - so12311

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接