进行Chunked编码传输的HTTP Response会在消息头部设置:
Transfer-Encoding: chunked
表示Content Body将用Chunked编码传输内容。
Chunked编码使用若干个Chunk串连而成,由一个标明长度为0 的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字 )和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF) 隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。具体的Chunk编码格式如下:
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
hex-no-zero = <HEX excluding "0">
chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
footer = *entity-header
RFC文档中的Chunked解码过程如下:
length := 0
read chunk-size, chunk-ext (if any) and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to entity-body
length := length + chunk-size
read chunk-size and CRLF
}
read entity-header
while (entity-header not empty) {
append entity-header to existing header fields
read entity-header
}
Content-Length := length
Remove "chunked" from Transfer-Encoding
最后提供一段PHP版本的chunked解码代码:
$chunk_size = ( integer ) hexdec ( fgets ( $socket_fd , 4096 ) );
while ( ! feof ( $socket_fd ) && $chunk_size > 0 ) {
$bodyContent .= fread ( $socket_fd , $chunk_size );
fread ( $socket_fd , 2 ); // skip /r/n
$chunk_size = ( integer ) hexdec ( fgets ( $socket_fd , 4096 ) );
}
==========================================================
Server Push技术
服务器推送(Server Push)的思想是由服务器主动发送信息,并与客户端保持连接,直至服务器或客户端有一方自行中断连接为止。
Server Push的优点在于减少了建立、销毁连接的时间,去除了无用的页面刷新,缺点是占用了大量端口和相关系统资源,单纯的Server Push无法支持大用户量的服务。
Server Push使用了multipart/x-mixed-replace这种MIME类型,报文范例格式如下:
Content-type:multipart/x-mixed-replace;boundary=ThisRandomString
–ThisRandomString
Content-type:text/plain
第一个对象的数据
–ThisRandomString
Content-type:text/plain
第二个(最后一个)对象的数据
–ThisRandomString–
每个数据块由三部分组成:一是Content-type之类的头标,二是数据正文,三是报文边界,每当客户端接收到新的头标时,原有文档将被清除,并被新的数据块填充。
Apache和IIS均支持Server Push技术,笔者推荐Linux/Unix下的Apache软件,它可以自由的增删相应模块,以满足较多连接状态下的高性能需求。
===========================================
PHP-Push技术实现刷新功能
Server push 前一段时间炒得很热的“推”技术,不过网上大部分都是cgi的资料,偶尔看到一个法国的网站上有这么个介绍,可惜法语看不懂,只能从他的程序中看懂点东 西,现整理个例子出来大家学习一下。可以用于聊天室的数据传输、网站上的新闻更新、等等各类更新频繁的页面。
以前做刷新主要通过页面上加标签。
< META HTTP-EQUIV=REFRESH CONTENT="time;URL=url" > |
或者使用javascript的timeout+reload,不过这种刷新的方法取决于时间的设定,无法连续的数据传输且时间不好确 定。采用了Server push的服务器在客户机做出一个请求后,和客户机建立一个永久的连接,然后服务器会根据客户机的请求不断地把数据包推向服务器。那些你觉察不到的延迟会 让你觉得服务器的响应和你的请求已经达到了同步的程度。
先来看一下例子再解释。
img.php |
这就是一个永久执行的页面(网络不断的情况下),不断输出图片的内容,下面是调用的页面。<img src=img.php>,然后打开你的netscape或其他非ie浏览器查看调用页面,好象没什么变化啊,别急,接着就是怎样变动1.jpg这 个图片了,写个另外的php页面来测试吧,比如弄2张图片按时间来覆盖1.jpg(这个方法自己想,用拷贝覆盖也行,只要1.jpg有变化)。这时你就看 到调用页面的图片自动更新了。
使用中你会发现个问题:怎么图片不自动更新了。这是由于客户机在一段时间内没有对服务器发生请求,也就是 某一段时间内没有新的内容向浏览器输入,可能发生连接超时现象。什么办法解决呢?可以在执行页面中加个向浏览器发送一个空信号,类似ftp连接方式,上面 页面中在do...while(1)间加个print("");
看完这个例子,应该知道怎么处理不断更新的内容了,关键在img.php页面中的处理(可以是检查新的内容并输出),调用的时候可以有img、script、frame等等。详细的其他使用方面请查看: http://www.npds.org/ 。
http://www.zeali.net/entry/129