注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

snoopyxdy的博客

https://github.com/DoubleSpout

 
 
 

日志

 
 

node.js搭建bigpipe demo时碰到的雷  

2011-12-15 09:29:37|  分类: node |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
bigpipe虽然也是分布加载网页,达到让用户边浏览,边加载的效果,但是bigpipe同以往ajax异步加载不同,它不会产生额外的http请求,当然避免了请求建立和释放的时间,同时也没有了多余的请求响应头,当然也减轻了服务器的压力。
更可以做到部分页面缓存,部分数据缓存,部分不缓存的状态。

在用node.js搭建demo时发现了一个小问题,当直接写如下代码后,前端页面并没有直接输出,而是等res.end()调用后再一起输出。
看代码:
res.write('1234567890');
res.write('abcdefghijklmn');
res.end();

一开始以为类似php+nginx,需要调整缓冲区的大小才能正常输出,因为php+nginx当时搭建bigpipe时,需要将nginx的缓冲区设置为很小,并且要将gzip关闭,具体可以参考相关文档。(其实关键就在这里,如果一开始没有去搭php+nginx那个环境,不会花这么多时间!5555~~)

于是找node.js v0.65 的api文档,发现没有找到相关可以设置的地方,于是去找node.js源码的http模块部分。
找到这一段:
OutgoingMessage.prototype._writeRaw = function(data, encoding) {
  if (this.connection &&
      this.connection._httpMessage === this &&
      this.connection.writable) {
    // There might be pending data in the this.output buffer.
    while (this.output.length) {
      if (!this.connection.writable) {
        this._buffer(data, encoding);
        return false;
      }
      var c = this.output.shift();
      var e = this.outputEncodings.shift();
      this.connection.write(c, e);
    }

    // Directly write to socket.
    return this.connection.write(data, encoding);
  } else {
    this._buffer(data, encoding);
    return false;
  }
};
也就是说,只有当 this.connection &&  this.connection._httpMessage === this &&  this.connection.writable 这个条件为false时会将data存入buffer,而这个_buffer(国际惯例,加下划线是私有方法的约定)方法就是将响应内容和encode放入两个数组中。

OutgoingMessage.prototype._buffer = function(data, encoding) {
  if (data.length === 0) return;
  var length = this.output.length;
  if (length === 0 || typeof data != 'string') {
    this.output.push(data);
    this.outputEncodings.push(encoding);
    return false;
  }
  var lastEncoding = this.outputEncodings[length - 1];
  var lastData = this.output[length - 1];
  if ((encoding && lastEncoding === encoding) ||
      (!encoding && data.constructor === lastData.constructor)) {
    this.output[length - 1] = lastData + data;
    return false;
  }
  this.output.push(data);
  this.outputEncodings.push(encoding);
  return false;
};

但是并没有提到需要判断缓存数组的bytelength啊,于是重新打开浏览器,查看网络传输,发现已经响应给客户端了,恍然大悟,原来是浏览器缓存干掉了输出。
顺便提一句,node.js源码写的很巧妙,当发现有同类型的string和utf-8响应给客户端,node.js并不是直接push到各自的数组,而是将字符串拼接,encoding数组不push的方式,可以减少一些开销。

后来发现ff会缓存512b的内容,chrome缓存1024b的内容,但是都只会缓存一次,以后都可以正常输出。

也就是说,只要服务器第一次响应的大小超过1kb就可以被上述2个浏览器正常输出了。以后再次响应无关大小,都可以正常输出。




  评论这张
 
阅读(2317)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016