我有以下node.js代码(截取代理):
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);
正如您所看到的,我有一个带有函数analyse()
的自定义Node.js插件,它返回一个字符串数组。然后我循环遍历这个数组并写出结果。
我遇到的问题是“2”没有写入!
我真的被困在这里,想知道是否有人可以提供帮助?
现在我知道(根据Node.js文档)“第一次调用response.write()时,它会将缓冲的头信息和第一个主体发送到客户端。第二次响应.write调用(),Node假定你将要传输数据,然后单独发送。也就是说,响应被缓冲到第一个主体块。“
我已尝试在response.end()
之后坚持使用response.write("2")
,但它仍无效。
如何刷新输出或关闭流媒体?
答案 0 :(得分:2)
您的分析功能是同步还是异步?如果它执行任何异步操作,看起来你在那里留下了一个空白,在分析调用之后写入最后一个数据块之前可能会结束响应。看起来它可能完全同步,但即使需要一段时间来处理,仍然可能在on数据监听器和on end侦听器之间存在竞争条件。
如果事实证明是真的发生了什么,或者a)在处理和中继代理数据时添加一些简单的互斥锁,防止响应过早结束;或者b)简单地将response.write(“2”)移动到proxy_response结束监听器中,就在response.end()行之前,因此它总是发生在同一个回调中,并且不能被抢占。
如果该结构变化所施加的限制不会妨碍您的整体应用程序设计,那么显然会容易得多。而且假设我已经正确地猜测了实际问题是什么,我可能完全偏离基础,但看起来确实可能。答案 1 :(得分:0)
我遇到了类似的问题,我发现这是因为&#34;内容长度&#34;头。客户希望响应主体具有一定的长度,如果超过该长度,则会切断多余的响应主体。因此,如果您要添加到响应正文但不调整&#34;内容长度&#34;标题会被发送到客户端,然后您就可以获得您正在查看的结果。
就我而言,我刚刚删除了&#34;内容长度&#34;标题并解决了这个问题,尽管我还没有充分意识到这样做的含义。