2014-07-28 3 views
3

Я пытаюсь написать простую реализацию клиент/сервер для передачи данных изображения между браузером и сервером node.js с использованием веб-узлов BinaryJS.binaryjs websockets утечка памяти

Следуя примерам api, я придумал что-то, что работает, однако, похоже, это утечка памяти, так как использование верхнего уровня для процесса узла постоянно увеличивается.

Я не очень хорошо разбираюсь в отладке 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 с запрошенным путем и передает данные через новый поток клиенту. Когда это завершается, клиент обновляет элемент страницы с данными.

Что мне здесь не хватает?

ответ

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

    }); 
}); 
+0

Я не знаком с 'binaryjs', но ответ @aecend кажется законным. То же самое относится к обработчикам событий javascript (всякий раз, когда вы видите '.on', знаете, что вы его уничтожаете). – GuyT

+0

На самом деле проблема createReadStream влияет не только на BinaryJS. Это проблема с самим Node.js. Когда потоковая передача завершена, предполагается закрыть дескриптор файла и автоматически освободить память, но это не так, поэтому вам нужно вручную закрыть ее. – aecend

+0

спасибо! Я думал, что что-то вроде этого должно продолжаться, должен был искать больше, я думаю. – so12311

0

Если мое понимание верное, вы хотите отправить двоичные данные от своих клиентов (браузеров) на ваш сервер (а не наоборот?), Используя потоки с BinaryJS. Если это правильно, то фрагмент кода, который вы дали, не делает то, что вы хотите.
Не могли бы вы рассказать нам больше?

+0

нет, я хочу передать данные с сервера в браузер. – so12311

Смежные вопросы