server推送(Server Push)html
推送技术的基础思想是将浏览器主动查询信息改成server主动发送信息。server发送一批数据,浏览器显示这些数据,同一时候保证与server的链接。当server需要再次发送一批数据时,浏览器显示数据并保持链接。之后,server仍然可以发送批量数据,浏览器继续显示数据,依次类推。算法
client拉曳(Client Pull)shell
在client拖曳技术中,server发送一批数据,在HTTP响应或文档头标记中插入指令,让浏览器“在5秒内再次装入这些数据”或“10秒内前往某URL装入数据”。当指定的时间达到时,client就依照server的指示去作,或者刷新当前数据,或者调入新的数据。编程
事实上push 和 pull 这两种技术手段很不一样,但目的差点儿一致,都是为了给终于用户方便的提供最新信息。浏览器
在server推送技术中,HTTP 链接一直保持着,直到server知道本身已结束发送数据并发送一个结束信号,或者client中断链接。而在client拖曳技术中,并不保持HTTP链接,相反,client被告知合时创建新链接,以及创建链接是获取什么数据。并发
在server推送中,奇异之处在于“multipart/mixed”格式的MIME,它可使一个报文(或HTTP响应)包括不少数据项、在client拖曳中,奇异之处在于HTTP响应头标(或等效的HTML元素),它能告知client在指定的延时时间后运行何种动做。dom
server推送一般效率要比client拖曳效率高,因为它没必要为兴许数据创建新的链接。因为始终保持链接,即便没有传输数据时也是这样,所以server必须愿意分配这些TCP/IPport,对于TCP/IPport数有限的server这将是一个严重的问题。性能
client拖曳效率低,因为这必须每次为传送数据创建新的链接。但是它没必要始终保持链接。动画
在实际状况中,创建HTTP链接一般需要花费至关多的时间,多达一秒甚至不少其它。所以从性能上考虑,server推送对于终于用户更有吸引力,特别是对于需要经常更新信息的状况下。this
server推送相对client拖曳的还有一点优点是,server推送相对照较easy控制。好比,server每一次推送时都保持一个链接,但它又随时可以关闭当中的不论什么链接,而不需要在server上设置特殊的算法。而client拖曳在相同的状况下要麻烦不少,它每次要与server创建链接,server为了处理将client拖曳请求与特定的终于用户匹配等状况,需要使用至关麻烦的算法。
假设实现server推送的CGI程序是使用Shell脚本语言编写的,有时会存在一些问题。好比,client终于用户中断链接,Shell程序一般不能注意到,这将使资源毫无用处的浪费掉,解决这一问题的办法是用Perl或者C来编写这类CGI程序,以使用户中断链接时能够结束执行。
如上所述,在server推送中,多个响应中链接始终保持,使server可在不论什么时间发送不少其它的数据。一个明显的优势是server全然能够控制更新数据的时间和频率。另外,这样的方法效率高,因为始终保持链接。缺点是保持链接状态会浪费server端的资源。server推送还比較easy中断。
接下来就大概说说server推送技术
server在响应请求时,HTTP使用MIME报文格式来封装数据。一般一个HTTP响应仅仅能包括一个数据块。但MIME有一种机制可用一个报文(或HTTP响应)表示将多个数据块,这样的机制就是成为“multipart/mixed”的标准MIME类型。multipart/mixed报文大致格式例如如下:
Content-type:multipart/mixed;boundary=ThisRandomString
--ThisRandomString
Content-type:text/plain
第一个对象的数据。
--ThisRandomString
Content-type:text/plain
第二个对象的数据。
--ThisRandomString--
上述报文包含两上数据块,两者的类型都是“text/plain”。最后一个“ThisRandomString”后的两条短线(--)表示报文结束,后面没有数据。
对于server推送,使用一个“multipart/mixed”类型的变种--multipart/x-mixed-replace。这里,“x-”表示属于实验类型。“replace”表示每一个新数据块都会取代前一个数据块。也就是说,新数据不是附加到旧数据以后,而是替代它。
如下是实际使用的“multipart/x-mixed-replace”类型:
Content-type:multipart/x-mixed-replace;boundary=ThisRandomString
--ThisRandomString
Content-type:text/plain
第一个对象的数据
--ThisRandomString
Content-type:text/plain
第二个(最后一个)对象的数据。
--ThisRandomString--
使用这一技术的关键是,server并不是推送整个“multipart/x-mixed-replace”报文,而是每次发送后数据块。
HTTP链接始终保持,于是server可以按本身需要的速度和频率推送新数据,两个数据块之间浏览器仅需在当前窗体等候,用户甚至可以到其它窗体作别的事情,当server需要发送新数据时,它仅仅是源(ABC输入法没那个字*&^$#)传输管道发送数据块,client对应的窗体进行自我更新。
在server推送技术中,“multipart/x-mixed-replace”类型的报文由惟一的边界线组成,这些边界线切割每个数据块。每个数据块都有本身的头标,于是能够指定对象相关的内容类型和其它信息。由于“multipart/x-mixed-replace”的特性是每一新数据块代替前一数据对象,于是浏览器中老是显示最新的数据对象。
“multipart/x-mixed-replace”报文没有结尾。也就是说,server可以永远保持链接,并发送所需的数据。假设用户再也不在浏览器窗体中显示数据流,或者浏览器到server间的链接中间(好比用户按“STOP”button),server的推送才会中断。这是人们使用server推送的典型方式。
当浏览器发现“Content-type”头标或到达头标结束处时,浏览器窗体中的前一个文档被清除,并開始显示下一个文档。发现下一个报文边界时,就以为当前数据块(文档)已经结束。
总之,server推送的数据由一组头标(一般包含“Content-type”)、数据自己和切割符(报文边界)三部分组成。浏览器看到切割符时,它保持状态不变,直到下一个数据块到达。
将以上概念进行用编程方法实现,就可以获得实际的server推送程序。好比,如下的Unix shell程序将使浏览器每5秒显示一次server上的进程列表:
#!/bin/sh
echo "HTTP/1.1 200"
echo "Content-type: multipart/x-mixed-replace;boundary=--ThisRandomString--"
echo ""
echo "--ThisRandomString--"
while true
do
echo "Content-type: text/html"
echo ""
echo "h2Processes on this machine updated every 5 seconds/h2"
echo "time:"
date
echo "p"
echo "plaintext"
ps -el
echo "--ThisRandomString--"
sleep 5
done
注意到,边界设置在sleep语句以前发送,这能够确保浏览器清除其缓冲区,并显示所接收到的最新数据。
NCSA HTTPD用户在内容类型中不能使用空格,包含边界參数。NCSA HTTPD仅仅能将不带空格字符的字符串做为内容类型。假设在内容类型行中存在空格(冒号后面的空格除外),空格后的不论什么文本都会被删除。
如下的演示样例是正确的:
Content-type: multipart/x-mixed-replace;boundary=ThisRandomString
而下例则不能正常工做,因为它在中间有空格:
Content-type: multipart/x-mixed-replace; boundary=ThisRandomString
server推送的还有一个长处是它可以针对单个内联图象进行。包含图象的文档可以由server定时或定周期进行更新。而实现这一点很easy:仅仅需使IMG元素的SRC属性指向推送一系列图象的URL就能够。
若是server推送用于单个内联图象,文档中的图象就会一次次被新推送来的图象所取代,而文档自己不需变化(若是文档没有进行server推送)。这样,WEB页面中有限的动画就可以为静态画面所取代。
client拖曳
client拖曳的一个简单使用方法是使文档按固定周期本身主动重载。好比,考虑如下的HTML文档:
<META HTTP-EQUIV="Refresh" CONTENT=1>
<TITLE>Document ONE</TITLE>
<H1>This is Document ONE!</H1>
Here's some text.<P>
假设将它加载支持动态文档的浏览器(Netscape 1.1以上,Internet Explorer和Mosaic也支持client拖曳),它将每隔一秒将本身重载一次。
由于META元素实际是在HTML文档中模拟HTTP响应头标,因此它能够告知浏览器将自身信息看成HTTP响应使用。上例中的META标记至关于:
Refresh:1
这样,实际上就是HTTP头标告知浏览器每一秒更新一次文档。假设需要延时是12秒,那么就是这种指令:
<META HTTP-RQUIV="Refresh" CONTENT=12>
那么它等效于:
Refresh:12
关于client的拖曳我也懒的继续写下去,关于怎么使client本身主动申请其它URL的数据话,请使用例如如下:
<META HTTP-EQUIV="Refresh" CONTENT="12;URL=http://icools.yeah.net/">
注意的是,此处的URL不能使用相对路径,必须全部指定。
当中时间间隔可以设置为0,这样浏览器在当前文档显示完成后,以最快的速度加载新的数据!