首页 > 类似BigPipe等的连接请求是怎样的?

类似BigPipe等的连接请求是怎样的?

想在网站中尝试类似BigPipe的加载技术,在实现后端页面分块输出的过程中,对请求处理上有很多疑问。。

主要有以下几个问题点:
+ http的响应头部如何处理?
+ chunkgzip能否共存 ?
+ 服务端如何处理请求并保持一个链接?

部分参考资料
分块传输编码


关注这个问题有一段时间了,本来想看看别人的回答,可惜貌似没等到。

BigPipe这个方案其实主要是一个server端HTTP协议上的应用,client端的响应脚本很容易写。之前分别使用Tornado、Node、.Net MVC实现过大概的模型,简单谈谈我的看法。

现代化的Web Framework写的都特别人性化,一般来说写BigPipe都会用到类似Response.flush的方法,除了裸的Node以外,都会自动帮你把响应流转换成Transfer-Encoding: chunked,因此服务端不需要你自己处理了,你只需要封装一下具体到语言/平台上的方案实现,比如分部视图的渲染,CSS/JS文件与模块关联以及依赖处理,数据的异步I/O调用之类的事情。

chunked和gzip也是可以共存的,但是具体表现起来会有点小问题。比如,当我在.net平台上实践并且开启GZIP的时候,每次flush出的结果都不完整,缺胳膊少腿的。因为,gzip会对buffer区内的数据细分然后压缩传输,而剩下的数据会在下一次flush的时候再传递过来。当然,之前实现的模型都比较原始,而且我也没有具体应用在项目上,所以不知道还会不会有什么坑。

至于第三个问题则完整表现在了http协议中对chunked的规则定义,以chunked定义的响应流最后需要一个长度为0的包来表示结束,一个完整的服务端web框架会自动保持住这个链接,等待对应函数全部执行完毕或者遇到了response.end,然后发送结束包,通知浏览器结束client端的请求,同时终结该请求在服务端上的生命周期。

最后 tips:
BigPipe具体到浏览器上还涉及一个渲染缓存的因素,做方案实验的时候,每一个请求的第一次flush的数据要多一些(我记得是要大于多少k,而且各个浏览器的限制还不一样),如果很短,比如<div>hi</div>的话,浏览器在收到传输包后是不会立刻进行渲染的。

上文虽然写了client的端的脚本会比较容易实现,但是如果应用的项目量级比较大,还会遇到一些别的诸如css数量限制之类的条件制约,那就需要case by case FE和BE一起想办法解决了,具体的经验可以看下新浪微博F2E Team之前写的一篇关于bigpipe的分享。

若有错误,还请斧正。

【热门文章】
【热门文章】