从头开始构建一个web即时通讯系统 - 基础 - web即时通讯系统的四种实现
页面刷新
页面刷新即通过刷新页面来更新聊天记录,通过页面提交来发送消息。毫无疑问,这种实现是最简单的,也是效率最差的。它意味着每一次收发消息都对应了一次httprequest,而http作为应用层协议,连接代价是相当大的。
ajax
ajax可以理解为xmlhttprequest,本质与页面刷新相同,但是页面上会有很多资源文件,比如图片、css、js、flash,这些文件会随着页面刷新并且没有做浏览器端缓存的时候更新。为了接收或者发送数十字节的消息而更新可能多达数百K字节的字节文件,显然是很愚蠢的。所以使用ajax来通讯,"只"需要为消息的获取或者发送而进行请求。ajax从这一点上是优于页面刷新的。
comet/server push
ajax为每一个消息的发送和接收建立一个新的http连接,并在短暂通讯完毕以后关闭。而server push的本质是http长连接,它的思路是,让服务器和浏览器维持着一个时间跨度很长的http连接,这个http连接可能大部分时候并不需要做什么,只在有消息的时候,向浏览器写入。所以这种方式避免了建立以及关闭http连接时大量的开销,提高了资源利用率。不过server push也有它的问题,在一个web服务器上,http连接数并非没有限制,所以如果把http连接数也看作是系统资源的话,server push确实是对于此资源的极大浪费了。
comet是server push的思路上的一种改进,它在ajax和server push之间使用了一种折中的策略,在高频率的通讯过程中,comet使用http长连接。一旦通讯变得不频繁,comet便释放http连接,并在下一次通讯的时候,是情况而定,看是否需要建立http长连接。
server push在asp.net中可以通过下面的代码片段实现:
protected void Page_Load(object sender, EventArgs e)
{
while (IsSessionEnd as bool)
{
lock (token as object)
{
Response.Write(message as string);
Response.Flush();
}
}
}
(当然,在实际编码中,as type的写法是不必要的,这里只是为了说明类型)
可以看到,在上面的代码片段中,会话结束前,Response.End()都不会被调用。
http://blog.csdn.net/huazhihao/article/details/4278699
socket/tcp
在页面刷新、ajax和server push的思路里,最重要的一个共同点就是基于http。http是web的基础,然而http并不符合即时通讯系统的思想,很大程度上是由于http几个特点:
[
http是无状态的,
http是一问一答的,
http是单播的,
http是应用层协议,通讯代价很大
]
然而http的下层协议tcp/udp就很适合用来做为即时通讯系统的通讯协议。可是在web标准里,一切都是基于http的。幸运的是,我们可以通过浏览器插件的信路来完成通讯,在java applet、flash和silverlight里,都提供了socket/tcp,并且dom和flash或silverlight是可以互操作的。这就意味着,dom也可以间接的使用socket来与服务器通讯。