Для моего первого проекта node.js я создаю прокси для некоторого вывода mjpeg. Теперь некоторые клиенты не могут читать поток так же быстро, как его получает сервер, поэтому я пропускаю кадры, чтобы они могли наверстать упущенное. В настоящее время я использую событие drain
объекта http.ServerResponse
, более или менее похожее на приведенное ниже, но поскольку drain
вызывается очень часто, мне интересно, есть ли лучший/более легкий подход (я не смог найти в документы потока с возможностью записи)
httpServer.on('request',function(request,response){
//skipped setting some headers etc.
res.socket.on('drain', function(){
res.drained = true;
res.draincounter = 0;
});
//followed by some unconditional first write (set drained to false first)
res.drained = false;
res.write(someData);
};
Теперь запись фреймов в клиент происходит так:
writeFrame = function(res,frame){
if(res.drained){
//nothing in queue, ready for new data
//first set drained to false
res.drained = false;
//and feed it more data
res.write(frame, 'binary');
} else if(res.draincounter > maxDroppedFrames){
//to many dropped frames in a row, disconnect
res.end();
} else {
res.draincounter++;
}
}
Но здесь используются настраиваемые свойства и много вызовов события слива (что может быть нормально, но с моим ограниченным опытом мне это не подходит). Вкратце мой вопрос таков:
Есть ли более эффективный способ определить, что буферы записи Writable Stream
пусты?
Редактировать: После перезапуска этого проекта с узлом 0.10.18 после того, как он был закрыт и бездействовал некоторое время, что-то ужасно неправильно, так как я больше не получаю события drain
(по крайней мере, не так, как описано выше). На данный момент я проверяю, находится ли res.socket.bufferSize
выше определенной отметки, чтобы решить, писать кадр mjpeg или нет, draincounter
все еще работает. Рекомендуемое pipe()
из потоковой документации в комментарии или не решение в моем случае проблема заключается не в записи всех данных о скорости клиента, а в удалении данных, когда скорость клиента ниже исходного потока.
Может ли кто-нибудь просветить меня, как правильно обрабатывать данные о противодавлении (если это не так)?
_writeableState
упоминается здесь только как инструмент "отладки",socket.bufferSize
упоминается здесь как один из тех, на которые стоит обратить внимание. Я думаю, что выберу его, хотя игра сhighWaterMark
все еще в моем списке как вариант. Поскольку в случае успехаres.draincounter
(или, в вашем случае,res.droppedFrames
) сбрасывается на0
, ему не нужно ничего такого сложного, как количество кадров в секунду. Ресурс заканчивается, когда нужно удалитьmaxDroppedFrames
в строке. 27.09.2013