基于Web的IM简介:http://www.maycode.com/index.php/hotspot/32-web20/272-
webim.html
Ajax轮询以及Comet模式:http://www.blogjava.net/rosen/archive/2009/02/11
/254309.html
基于 HTTP
长连接的“服务器推”技术:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/
claros chat: http://www.claros.org/web/download.do
pushlets: http://www.pushlets.com/
pushlet 原理:http://blog.youkuaiyun.com/yxw246/archive/2008/05/08/2418255.aspx
Comet技术的两种实现:基于AJAX长轮询的方式和基于iframe及htmlfile流的方式。
一、基于AJAX轮询方式与传统AJAX方式的区别:
1. 服务器端会阻塞请求直到有数据传递或超时才返回。
2. 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
3.
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所
有的信息取回。
采用这种方式实现的技术有meboo和pushlet chat。
二、基于iframe及htmlfile流的方式
这个方式和AJAX方式原理相同,只是浏览器一直会显示正在连接状态,gtalk采用htmlfile技术解决了此问题。Zeitoun
网站提供的 comet-iframe.tar.gz,封装了一个基于 iframe 和 htmlfile 的 JavaScript comet
对象,支持 IE、Mozilla Firefox
浏览器,可以作为参考:http://www.zeitoun.net/articles/comet_and_php/start
三、Http长连接的编程原则
1、不要在同一个客户端开启超过两个的http长连接,这个是受http协议限制的。
2、控制信息和数据信息使用不同的http连接。
3、在客户端和服务器端保持“心跳”信息。
四、Pushlet框架学习
Pushlet框架是用后台采用java实现,前台技术有AJAX和Iframe两种。设计思想采用观察者模式。
学习资料:
1.
短轮询(polling)
:核心思想是客户端定时去服务器取消息。为了实现即时效果,轮询的间隔必须设计得足够短,另外为了操作的流畅,需要使用Ajax
来发送请求。本人的QGYWebIM
就是采用的此方案。这种方案的优点是:后端程序编写比较容易,发送完响应信息马上断开连接,不会占用太多服务器资源。缺点是一般情况下,频繁的请求中有大
半是无用,这些冗余请求无形中浪费了带宽和服务器资源。我们可以通过判断用户的活跃程度来决策请求服务器的间隔,我在 51
的一个帖子提到过这种方法,但是间隔一旦长了,消息的传送就有延时,违背了即时聊天的初衷了。
2.
长轮询(long- polling)
:基本原理是客户端向服务器发送请求,服务器接到请求后hold
住连接,直到有新消息才返回响应信息并关闭连接,连接被断开期间用户的新信息会被服务器缓存起来。客户端处理完响应信息后再向服务器发送新的请求。这种做
法的优势是如果用户一直没新消息,客户端不会频繁的轮询去服务器取消息,节省了流量,但是服务器维持长连接是很消耗资源的。具体实现起来,前端这边基本不
需要什么改动,依然是用Ajax
轮询取信息,后端需要在没有新消息时处理一下。
3.
长连接(streaming)
:其实很早以前就有人使用这种技术来实现聊天室的通讯。以前在页面中嵌入一个 iframe
,iframe
里放一个使用长连接页面,服务器有新消息就会及时的在iframe
里反映出来,再依靠客户端的脚本解析出来就OK
了。这样做一个比较严重的问题是:使用iframe
请求长连接时,无论是IE
还是firefox
都会认为页面没有加载完而显示进度条,很难看。不过这个问题是可以解决的。firefox
支持了Streaming Ajax
,在readyState
为3
的时候就能接受数据,所以问题不大;IE
则只能在readyState
为4
,即连接断开时才能得到返回值。但是伟大的Google
工程师使用了一个hack
成功的解决了这个问题:使用一个被称为“htmlfile
”的ActiveX
,把iframe
放在这个 ActiveX
里就OK
了。
// we were served from child.example.com but
// have already set document.domain to example.com
var currentDomain = "http://exmaple.com/";
var dataStreamUrl = currentDomain+"path/to/server.cgi";
var transferDoc = new ActiveXObject("htmlfile"); // !?!
// make sure it's really scriptable
transferDoc.open();
transferDoc.write("");
transferDoc.write("<script type="text/javascript"><!--
document.domain='"+currentDomain+"';
// --></script>");
transferDoc.write("");
transferDoc.close();
// set the iframe up to call the server for data
var ifrDiv = transferDoc.createElement_x_x("div");
transferDoc.appendChild(ifrDiv);
// start communicating
ifrDiv.innerHTML = "";
无疑,使用长连接对于用户来说是最好的方案,用户体验最好(消息能及时的到达)、占用用户带宽最少(不会发送无用的请求),但是会增加服务器的开销;长轮
询是折中方案,Facebook IM
就是采用这种方案,不过做了一点改动:客户端发起的每个连接服务器都hold10S
,这10S
中新消息会源源不断的返回给客户端,10s
后连接关闭,客户端发起下一个连接。这样做是因为Facebook
的用户会不断的打开、关闭新页面,如果每个页面都建立一个永久的长连接,会阻塞浏览器其他请求,服务器也会吃不消的;短轮询因为实现起来简单,适用于小型
应用。
http://www.qgy18.com/2008/08/webim-design-transport/
常规来说,有以下方法:
1
。使用JavaApplet
作为中介和服务器交互。不过用户必须为这交互过程编写Java
代码。
2
。使用ActiveX
控件做中介。但是ActiveX
的权限太大,未一定能得到客户信任。
3
。使用IFrame
把某个窗体隐藏,然后用传统的方法进行GET
和POST
。不过请求数据的发送和状态都非常难控制
4
。使用MSXML
的XMLHTTP
来进行数据的传输。这个只适应于Win98
或安装了MSXML(IE6
自带的Windows
系统)
5
。使用dotnet
的Assembly
来写客户端程序。不过这需要客户端安装dotnet
组件。
Lostinet.Janc(
以下称为Janc)
是一个实现和服务器交互的组件。
实际上,它没有提供新的方法来进行和服务器的交互。
它的编写目的就只有一个:为了方便:
要方便代码的编写,要方便程序的发布。。
Lostinet.Janc
采用第4
种方法(
使用Microsoft.XMLHTTP)
和服务器交互。