服务器推送(Server Push)
推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息。服务器发送一批数据,浏览器显示这些数据,同时保证与服务器的连接。当服务器需要再次发送一批数据时,浏览器显示数据并保持连接。以后,服务器仍然可以发送批量数据,浏览器继续显示数据,依次类推。
客户端拉曳(Client Pull)
在客户端拖曳技术中,服务器发送一批数据,在HTTP响应或文档头标记中插入指令,让浏览器“在5秒内再次装入这些数据”或“10秒内前往某URL装入数据”。当指定的时间达到时,客户端就按照服务器的指示去做,或者刷新当前数据,或者调入新的数据。
其实push 和 pull 这两种技术手段非常不同,但目的几乎一致,都是为了给最终用户方便的提供最新信息。
在服务器推送技术中,HTTP 连接一直保持着,直到服务器知道自己已结束发送数据并发送一个结束信号,或者客户端中断连接。而在客户端拖曳技术中,并不保持HTTP连接,相反,客户端被告知合时建立新连接,以及建立连接是获取什么数据。
在服务器推送中,奇妙之处在于“multipart/mixed”格式的MIME,它能够使一个报文(或HTTP响应)包含许多数据项、在客户端拖曳中,奇妙之处在于HTTP响应头标(或等效的HTML元素),它能告知客户端在指定的延时时间后执行何种动作。
服务器推送通常效率要比客户端拖曳效率高,因为它不必为后续数据建立新的连接。由于始终保持连接,即使没有数据传输时也是这样,因此服务器必须愿意分配这些TCP/IP端口,对于TCP/IP端口数有限的服务器这将是一个严重的问题。
客户端拖曳效率低,因为这必须每次为传送数据建立新的连接。但是它不必始终保持连接。
在实际情况中,建立HTTP连接通常需要花费相当多的时间,多达一秒甚至更多。因此从性能上考虑,服务器推送对于最终用户更有吸引力,特别是对于需要经常更新信息的情况下。
服
务器推送相对客户端拖曳的另一点优势是,服务器推送相对比较容易控制。例如,服务器每一次推送时都保持一个连接,但它又随时可以关闭其中的任何连接,而不
需要在服务器上设置特殊的算法。而客户端拖曳在同样的情况下要麻烦许多,它每次要与服务器建立连接,服务器为了处理将客户端拖曳请求与特定的最终用户匹配
等情况,需要使用相当麻烦的算法。
如果实现服务器推送的CGI程序是使用Shell脚本语言编写的,有
时会存在一些问题。例如,客户端最终用户中断连接,Shell程序通常不能注意到,这将使资源毫无用处的浪费掉,解决这一问题的办法是用Perl或者C来
编写这类CGI程序,以使用户中断连接时能够结束运行。
如上所述,在服务器推送中,多个响应中连接始终保持,使服务器可在任何时间发送更多的数据。一个明显的好处是服务器完全能够控制更新数据的时间和频率。另外,这种方法效率高,因为始终保持连接。缺点是保持连接状态会浪费服务器端的资源。服务器推送还比较容易中断。
接下来就大概说说服务器推送技术
服务器在响应请求时,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”后的两条短线(--)表示报文结束,后面没有数据。
对
于服务器推送,使用一个“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--
使用这一技术的关键是,服务器并不是推送整个“multipart/x-mixed-replace”报文,而是每次发送后数据块。
HTTP连接始终保持,因而服务器可以按自己需要的速度和频率推送新数据,两个数据块之间浏览器仅需在当前窗口等候,用户甚至可以到其他窗口做别的事情,
当服务器需要发送新数据时,它只是源(ABC输入法没那个字*&^$#)传输管道发送数据块,客户端相应的窗口进行自我更新。
在
服务器推送技术中,“multipart/x-mixed-replace”类型的报文由唯一的边界线组成,这些边界线分割每个数据块。每个数据块都有自
己的头标,因而能够指定对象相关的内容类型和其他信息。由于“multipart/x-mixed-replace”的特性是每一新数据块取代前一数据对
象,因而浏览器中总是显示最新的数据对象。
“multipart/x-mixed-replace”报文没有结尾。也就是说,服务器可以永远保持连接,并发送所需的数据。如果用户不再在浏览器窗口
中显示数据流,或者浏览器到服务器间的连接中间(例如用户按“STOP”按钮),服务器的推送才会中断。这是人们使用服务器推送的典型方式。
当浏览器发现“Content-type”头标或到达头标结束处时,浏览器窗口中的前一个文档被清除,并开始显示下一个文档。发现下一个报文边界时,就认为当前数据块(文档)已经结束。
总之,服务器推送的数据由一组头标(通常包括“Content-type”)、数据本身和分割符(报文边界)三部分组成。浏览器看到分割符时,它保持状态不变,直到下一个数据块到达。
将以上概念进行用编程方法实现,就可以得到实际的服务器推送程序。例如,下面的Unix shell程序将使浏览器每5秒显示一次服务器上的进程列表:
#!/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
服务器推送的另一个优点是它可以针对单个内联图象进行。包括图象的文档可以由服务器定时或定周期进行更新。而实现这一点非常简单:只需使IMG元素的SRC属性指向推送一系列图象的URL即可。
如果服务器推送用于单个内联图象,文档中的图象就会一次次被新推送来的图象所代替,而文档本身不需变化(假设文档没有进行服务器推送)。这样,WEB页面中有限的动画就可以为静态画面所代替。
客户端拖曳
客户端拖曳的一个简单用法是使文档按固定周期自动重载。例如,考虑下面的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也支持客户端拖曳),它将每隔一秒将自己重载一次。
由于META元素实际是在HTML文档中模拟HTTP响应头标,所以它能够告知浏览器将自身信息当作HTTP响应使用。上例中的META标记相当于:
Refresh:1
这样,实际上就是HTTP头标告知浏览器每一秒更新一次文档。如果需要延时是12秒,那么就是这样的指令:
<META HTTP-RQUIV="Refresh" CONTENT=12>
那么它等效于:
Refresh:12
关于客户端的拖曳我也懒的继续写下去,关于怎么使客户端自动申请其他URL的数据话,请使用如下:
<META HTTP-EQUIV="Refresh" CONTENT="12;URL=http://icools.yeah.net/">
注意的是,此处的URL不能使用相对路径,必须全部指定。
其中时间间隔可以设置为0,这样浏览器在当前文档显示完毕后,以最快的速度载入新的数据!
希望大家受用。
posted @
2006-12-31 22:57 Syhan 阅读(532) |
评论 (0) |
编辑
昨晚在sun的网站上看到一篇
文章比较有意思,简单翻译了一下
为什么swing叫做swing
今天我被问起
swing这个产品的名字,也是Java SE package中用来创建GUI和相关的API。因为我在99年6月在Sun开始的时候我只记得Swing被用来作为代码的名字并且由此卡住。所以我问一位最初Swing的工程师并且也是Swing小组的正是经理Jeff Dinkins。接下来是故事,来自Jeff。
Georges Saab提出了这个名字……
故事是:项目组去Hobbes吃中饭,并且话题转向了命名我们正在写的新的工具。直到那时代码的名字还是叫做KFC,选自我们的的项目经理(Rick Levenson)作为一个方式确定我们最好在发布(shippping)之前取一个更好的名字,他知道根本不可能叫做“KFC”,也叫做Kentucky Fired Chicken将不会被律师所允许。
一些名字被提出来包括Juliet和Carousel。还有更多的,但是没有一个让我们感觉“”还可以的“。
最后在中饭以后,当我们开车会Sun的时候,Amy Fowler(项目中的首席工程师)问我们最后面的成员,Georges Saab,”Georges,你知道在San Francisco有什么新鲜事情发生吗?“
Georges回答说”摆动跳舞正在变大(Swing dancing is getting to be really big)“。就是它,我们都认为很完美。当我们回到办公室我做了了全面的搜索并且把”kfc“替换为”swing“,接下来的就是历史了。
多谢了这一小段历史。Jeff Rick Levenson是一有有趣动力技术能力的经理。
编辑增加:Jeff贴了一个链向这篇blog的链接在
javadesktop.org伴随着很精彩的画(Rick在左Georges在右):

谢谢你,Jeff!!
────Sharon Zakhour
posted @
2006-12-20 10:45 Syhan 阅读(150) |
评论 (4) |
编辑

感觉太酷了,不过在我的ubuntu上显示中文还是方块,郁闷,不过真不愧是SourceForge.net本月推荐项目啊,比我第一次看到GoogleEarth还要震撼,感兴趣的朋友可以去http://stellarium.sourceforge.net/看看,ubuntu的源里面有,直接搜索stellarium就可以了
posted @
2006-12-16 22:45 Syhan 阅读(127) |
评论 (0) |
编辑
自己太懒了,很久都没有写blog了……
问题:
使用的linux的distribution由原来的SuSE 10.1换成了现在的Ubuntu从 6.06 Dapper再到6.06.1再到6.10 Edgy, 其间遇到了很多困难:
分述如下:
1 版本更新后无法进入系统。说实话linux版本的升级真实一件很玄的事情,我一共作了两次,一次成功了,一次没有,两次的区别在于失败的那次我安装了beryl,打开了3d桌面。我现在还是觉得完全重新安装是个不错的选择。
2 OpenOffice不能打开(之前是好的,但是好像突然就不能使用了,回想起来从能用到不能用期间我只安装了ATI
的官方的驱动8.31.5),具体表现为Splash过了之后没有任何东西弹出来,使用命令行打开则会报一堆烦人的错,好像是什么fork
abnormaly,网上搜索了一下,说是与SCIM冲突,果然,卸载掉之后,OO正常。
3 乱码问题,我上网搜了一下,这是由于转码造成的,在一些qtk+程序上比较明显,例如xmms,具体的解决可以看这个
页面,不过值得注意的一点是我当时按照这个做并没与成功,还要修改一下X.org这个文件让xwindow搜索指定路径的上字体文件。gftp需要将远程连接字符集设成gbk(但是我发觉还是不好用,估计是服务器的问题)
4 挂载磁盘,主要就是修改/etc/fstab文件,装了一个ntfs-3g感觉对ntfs的格式支持很cool,早知道当时就不特别把文档那个盘格成fat32了。
5
输入法的问题,如前所述,为了让OO运行起来,我卸载了scim,但是输入法怎么办?scim虽然用起来挺顺手但是与诸多软件冲突,例如vmware,
adobereader等等,我最后还是换了fcitx,由于我比较偏爱英文的界面,所以选择的locale是en.UTF-8,输入的时候全是小方框,
按照作者的说法需要修改一下配置文件,可是无论我怎么修改都不行。无奈,最后碰巧google的时候看到
这个,我修改了language-selector.conf,这里于是产生了一个取舍的问题,要美化还是输入法,或者输入法还是OpenOffice,无奈……我还是要输入法……
6 MySQL 不能连接,这个也比较郁闷,估计是授权的问题,但是想不通的是我都授权了用户了,也修改了my.cnf,结果连接的时候还是connection refuesed,这个我没办法了,最后装了个PostgreSQL了事。
我的一点想法:
1 对JAVA感觉越来越好了,最近在看Core Java
Volumn2,真是好书,有这么多我以前不了解不知道不清楚不明了的东西,不过说到最后这个还是比较依赖API的,下载了SUN开源的Open
JDK的sources,比较搞笑的一点是用netbeans5.5编译的话会出现”recompiling compiler with
itself“,不知道用eclipse会发生什么情况。看了点SCJP的培训资料,觉得难度还可以,想赶最后一班车。
2
Ubuntu用的越来越顺手了,特别是debian的package制度,真是“自家开超市,想要什么随便拿”,源的速度也很快,更重要的是用户群比较
大,这个比SuSE强。算了一下,用过Gentoo,
SuSE,Ubuntu(期间也用过一阵子的FC),Gentoo是最难的,SuSE和FC都觉得不够自由,还是觉得ubuntu最好,当然,首先要用的
顺手。有时间想装个BSD搞搞服务器知识,呵呵。
3 想学习Latex/Tex、Ruby on Rails、Emacs/Vi,看了一点资料。
4 还有很多事情要做,背单词,编译原理、数据库原理、模糊数学的各个作业……
5 Freemind这个软件不错,可以用了画脑图(mindmap),源里面没有,但是可以下到相应的deb包,推荐Firefox的两个extention:Google Browser Sync和CHM reader,前一个在google的主页可以下到,是个同步浏览器设置的东东,后一个是来阅读chm的,鉴于xchm、chmsee、gnochm都有一些自己的问题,还是这个最好最快。
这里不得不小小bs一下blogjava的blog,我的ff一激活输入的控件必定假死,cnblogs倒是没有这个问题……
posted @
2006-12-14 11:27 Syhan 阅读(112) |
评论 (0) |
编辑
qmail的简单配置和发信使用
在Gentoo下安装软件比较简单,在命令行的情况下直接通过emerge +软件名即可从网上下载到相应软件的最新版本,并且Gentoo的protage方式会自动得到软件的依存关系,并将相应需要的其余软件一并下载并安装。由于sendmail与qmail冲突,所以第一步是将sendmail卸载掉。
# emerge –unmerge sendmail
安装需要网络支持(当然也可以将文件下载到本机安装),所以网络需要配置好,可以先通过命令行
# ifconfig
# route
察看自己的网络设置,设置相应的ip地址、网关、子网掩码、DNS等等需要修改/etc/conf.d/net和/etc/resolv.conf两个文件。
net文件设置按如下格式
# This network configuration was written by net-setup
iface_eth0="192.168.18.39 broadcast 192.168.18.255 netmask 255.255.255.0"
gateway="eth0/192.168.18.10"
resolv.conf设置按如下格式
domain grandview
nameserver 219.141.140.10
然后将即可开始安装qmail
# emerge qmail
Gentoo会同时自动为你安装daemontools和ucspi-tcp,然后自动编译添加用户组、服务等等,这些都不用我们人为干预,系统会帮你搞定。就是时间有点长,可以考虑泡杯茶休息一下。
安装编译完后会建立/var/qmail、/var/log/qmail等等相关目录
这时你可以测试一下安装
# qmailctl stat
如果一切正常的话,应该看到如下输出
/service/qmail-send: up (pid 30303) 187 seconds
/service/qmail-send/log: up (pid 30304) 187 seconds
/service/qmail-smtpd: up (pid 30305) 187 seconds
/service/qmail-smtpd/log: up (pid 30308) 187 seconds
messages in queue: 0
messages in queue but not yet preprocessed: 0
接下来需要简单配置一下qmail(参考life with qmail)
qmail的基本配置文件都在/var/qmail/control目录下,可以根据需要进行修改
邮件用户通常并不直接发送邮件. 典型的方式是利用邮件用户代理(Mail User Agent, MUA)程序, 例如 pine 或者 mutt 编写并发送邮件. MUA程序调用MTA传送邮件. 这个处理邮件到MTA的调用过程称为注入(injection). 我们可以通过MTA提供的的特定程序完成注入,在qmail系统下我们有qmail-inject
下面我们按照/var/qmail/docs/TEST.delivery来进行发信
发送一封空邮件到test@test.com可以采取
# echo to:test@test.com | /var/qmail/bin/qmail-inject
发送一封邮件到test@test.com
# /var/qmail/bin/qmail-inject
To: test@test.com
From:test
Subject:this is a test
Hey, this is a test from syh!!
(用Ctrl + D 表示结束)
如果不出意外应该能在/var/log/qmail/current文件中看到类似下面的显示
1 @4000000038c3eeb027f41c7c new msg 93869
2 @4000000038c3eeb027f6b0a4 info msg 93869: bytes 2343 from <dave@sill.org> qp 18695 uid 49491
3 @4000000038c3eeb02877ee94 starting delivery 2392: msg 93869 to remote test@test.com
4 @4000000038c3eeb0287b55ac status: local 0/10 remote 1/20
5 @4000000038c3eeb104a13804 delivery 2392: success: 209.85.127.177_accepted_message.
/Remote_host_said:_250_CAA01516_Message_accepted_for_delivery/
6 @4000000038c3eeb104a4492c status: local 0/10 remote 0/20
7 @4000000038c3eeb104a6ecf4 end msg 93869
第 1 行指出qmail接收到一条新邮件, 邮件的队列ID是93869. 队列ID是 /var/qmail/queue/mess/NN/ 包含这个邮件的队列文件的 i-node 节点值. 队列ID将在这个消息存在于队列的过程中保持全局唯一.
第 2 行表明邮件来自 dave@sill.org, 并且大小为2343字节.
第 3 行表明qmail-remote开始传送这个邮件到lwq@w3.to, 并且为这个传送指定了ID 2392.
第 4 行指出 0 个本地传送和 1 个远程传送处于等待状态.
第 5 行显示出 ID 2392 这个传送已经成功完成, 并且返回远程主机的回应, 这个回应里面常常包含了远程邮件管理员对于跟踪这个传送的有用信息. 在我们这个例子里面, "CAA01516"是远程系统的传送ID.
第 6 行指出 0 个本地传送和 0个远程传送处于等待状态. 也就是传送已经完成了.
第 7 行指出这个消息已经被传送完毕并且被移出队列. 这个时候, 队列ID 93869, 已经可以重用于其他传送ID了.
这样你就通过qmail将一份邮件发出去了。
posted @
2006-07-07 15:12 Syhan 阅读(112) |
评论 (0) |
编辑
最近学了一点Struts。
首先这是一种设计模式,模型-视图-控制器的MVC三层架构,这样的设计使得工程中各个模块的耦合度很低,维护和修改起来比较容易,往往只需要修改个别配置文件(Struts-config.xml)基本不会导致一处修改而许多地方都要返工的情况。
Model也就是模型组件在Struts主要就是一个Formbean,通过它来获取视图(View)组件输入的值,通过一系列的get/set方法来获取,同时验证用户的输入,需要注意的是bean里面的私有成员需要与view里面的标签里的property值相对应,否则会提示找不到getter/setter方法。
View,顾名思义就是视图组件,在Struts里表现为Jsp文件,就是展示给用户看的那个东东,按照Struts的设计思想,jsp里是不应该出现java代码的。Struts同时提供了丰富的标签库来代替html自身的标签和实现相应的其他的功能,定义在诸如struts-html.tld的文件里。
Controller也是一个java文件,起的就是控制的作用,比如和数据库连接验证用户的数据是否合法(而model只是验证是否合法,比如email地址是否有“@”符号等等),验证成功了后如何跳转,失败后如何等等。
Struts 里有丰富的标签,常用的有<bean><logic><html>三个,其中<html>是和Struts框架联系在一起的,所以不能脱离Struts使用,而其他的都可以通过加入.tld文件来使用
tiles是Struts的一个模板机制,类似于JSP里的<jsp:include>
简单的说来,Struts无非是这么个东西,用户向浏览器中的页面填写数据,然后点击提交,这些数据会被交给相应的formbean也就是Model组件处理验证合法性,若通过(或validate=“false”)则将控制权交给action,action处理业务逻辑部分,最后跳转到相应的成功或者失败的页面。其中所有的配置信息都是在Struts-config.xml文件中定义的。
Struts的初学者例子有很多,网上到处都是,我就不列举了。要考试了,我ft
posted @
2006-06-03 14:34 Syhan 阅读(94) |
评论 (1) |
编辑