2012-02-23 2 views
0

Я следующий Node.js код (перехватывающей прокси):Node.js - response.write (...) не работает

var http = require('http'); 
var eamorr=require('./Eamorr_addon/out/Release/Eamorr_addon'); 


http.createServer(function(request,response){ 
    var proxy=http.createClient(80,request.headers['host']) 
    var proxy_request=proxy.request(request.method,request.url,request.headers); 
    proxy_request.addListener('response',function(proxy_response){ 
    proxy_response.addListener('data',function(chunk){ 
     var arr=eamorr.analyse(chunk); 
     for(var i=0;i<arr.length;i++){ 
      //console.log(arr[i]+"\n\n"); 
      response.write(arr[i]); 
     } 
     response.write("2"); //this doesn't get written! 
    }); 
    proxy_response.addListener('end',function(){ 
     response.end(); 
    }); 
    response.writeHead(proxy_response.statusCode,proxy_response.headers); 
    }); 
    request.addListener('data',function(chunk){ 
    proxy_request.write(chunk,'binary'); 
    }); 
    request.addListener('end',function(){ 
    proxy_request.end(); 
    }); 
}).listen(10002); 

Как вы можете видеть, у меня есть обычай Node.js addon с функцией analyse(), которая возвращает массив строк. Затем я перебираю этот массив и записываю результат.

Проблема, которую я испытываю, заключается в том, что «2» не написано!

Я действительно застрял здесь и задавался вопросом, может ли кто-нибудь помочь?

Теперь я знаю, что (в соответствии с документами Node.js), что «в первый раз вызывается response.write(), он отправляет клиенту информацию о буферизованном заголовке и первое тело. Второй ответ времени. write(), Node предполагает, что вы собираетесь передавать данные и посылает их отдельно. То есть, ответ буферизуется до первого куска тела ».

Я пробовал придерживаться response.end() после response.write("2"), но он все равно не сработает.

Как очистить выход или отключить потоковое вещание?

+1

Как насчет цикла for, который записывает элементы массива в ответ, работает ли это, например, с помощью большого массива? – supertopi

+0

Эй, только что вернулся с моего обеда. Он работает правильно для небольших массивов (я возвращаю только небольшие массивы). – Eamorr

+0

Вы не должны использовать кодировку 'binary'. Не уверен, что это источник проблемы. – loganfsmyth

ответ

2

Является ли ваша функция анализа синхронной или асинхронной? Если он делает что-либо асинхронное, похоже, что вы оставляете пробел там, где ответ может быть закончен до того, как последний фрагмент данных будет записан после вызова анализа. Похоже, что это, вероятно, полностью синхронно, но даже если потребуется немного времени для обработки, все равно может быть возможным наличие состояния гонки между прослушивателем данных и запуском слушателя.

Если это будет действительно то, что происходит, то: a) добавьте простой мьютекс какого-либо рода при обработке и передаче данных прокси-сервера, предотвращая преждевременное завершение ответа; или b) просто переместите response.write («2») в прослушиватель конца proxy_response прямо перед линией response.end(), поэтому он всегда происходит в одном обратном вызове и не может быть предварительно упущен.

b, очевидно, будет намного проще, если ограничения, налагаемые этой структурой, не мешают вашему общему дизайну приложения. И это предполагает, что я правильно оценил, какова фактическая проблема, я могу быть полностью вне базы, но она выглядит возможной.

+0

Большое спасибо за ваш подробный ответ. Я попробовал ваше предложение b) - написание нескольких строк «2» непосредственно перед response.end(). Они появляются в Wireshark, но не получают мою программу Node.js на другом конце. Я сейчас собираюсь попробовать предложение мьютекса. Я изо всех сил пытаюсь разобраться в этом.Моя функция (анализ) является синхронной, но она находится внутри асинхронного блока, поэтому в программе не будет никаких заметных зависаний. – Eamorr

0

У меня была аналогичная проблема, и я узнал, что это связано с заголовком «длина содержимого». Клиент ожидает, что тело ответа будет иметь определенную длину, и если оно превышает эту длину, оно отсекает избыток. Поэтому, если вы добавляете в тело ответа, но не корректируете заголовок «длина контента», который отправляется клиенту, вы получите результат, который видите.

В моем случае я просто удалил заголовок «длина контента», и он исправил проблему, хотя я еще не полностью осознал последствия этого.

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