利用bigpipe机制实现页面模块的异步渲染 chunked技术

晨曦之光 发布于 2012/03/09 14:50
阅读 230
收藏 1

 bigpipe基于HTTP/1.1 支持的chunked编码,可以由浏览器接收到服务器发送的chunked块后,立即解析该块代码。因为chunked编码使消息主体成块发送,每块有自己的大小指示器,在所有的块之后会紧接着一个可选的包含实体头域的尾部。这种编码充许发送端能动态生成内容,并能携带能让接收端判断消息是否接收完整的有用信息。
    每块的大小指示器chunk-size为16进制数字字符串,块编码以大小为0的块结束,紧接着是trailer(尾部),trailer以一个空行终止。
    如下图:

图中蓝框区域所示该http响应为chunked编码
    图种红框部分为每一个chunked块,其中比如第一个块的14a就是这个块的大小指示器chunk-size,紧接着的就是块的内容。在最后一个内容块后面会增加一个大小为0的块,以标志所有块结束,所以真实的块数量会比可见的内容块数量多一个。

    点击以下地址可以查看该实例,可以明显地看到每一行的延迟输出。
    <chunked块输出实例>(写完博文后发现我那破空间没支持chunked编码,大家拿源码自己在本地运行吧╮(╯▽╰)╭)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title></title>
	</head>
	<body>
		111111111111111111111111111111111<br/>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		222222222222222222222222222222222<br/>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		333333333333333333333333333333333<br/>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		444444444444444444444444444444444<br/>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		555555555555555555555555555555555<br/>
	</body>
</html>


大家可以看到,在PHP中,是通过flush()语句来将缓冲区里的数据实时发送到请求端,实现起来并不复杂。

    ok,那么我们如何来通过chunked编码块的这个特性来实现页面元素的异步渲染呢?是由服务器端输出分块的内容,其实就是一段<script>标签内容,<script>标签添加到页面后,会由标签内的js代码来作页面模块渲染的控制,请看以下示例:
    
    <chunked块模块渲染>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>bigpipe demo</title>
		<script type="text/javascript">
			function render(nodeID,html){
				document.getElementById(nodeID).innerHTML=html;
			}
		</script>
	</head>
	<body>
		<div id="node1"><strong>loading...<strong></div>
		<div id="node2"><strong>loading...<strong></div>
		<div id="node3"><strong>loading...<strong></div>
		<div id="node4"><strong>loading...<strong></div>
		<script type="text/javascript">render("node1",'<div>lalalalal~~~~<br/>lalalalal~~~~<br/>lalalalal~~~~<br/>lalalalal~~~~<br/>lalalalal~~~~<br/></div>')</script>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		<script type="text/javascript">render("node2",'<div style="color:blue;">wa~~kakakakakakka~~~~~<br/>wa~~kakakakakakka~~~~~<br/>wa~~kakakakakakka~~~~~<br/></div>')</script>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		<script type="text/javascript">render("node3",'<div style="color:red;">wohahah...wohhahahah...<br/>woowowowo~~~~</div>')</script>
		<?php
			ob_flush();
			flush();
			sleep(2);
		?>
		<script type="text/javascript">render("node4",'<div>go~go~go~~~a~le~a~le~a~le~~~</div>')</script>
		<?php
			ob_flush();
			flush();
		?>
	</body>
</html>


 


原文链接:http://blog.csdn.net/21aspnet/article/details/6616428
加载中
返回顶部
顶部