`
lbsp59lbsp
  • 浏览: 14097 次
社区版块
存档分类
最新评论

AJAX 长轮询

 
阅读更多

AJAX 长轮询
2010年06月24日
  基于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-co met/
  claros chat: http://www.claros.org/web/download.do
  pushlets: http://www.pushlets.com/
  pushlet 原理:http://blog.csdn.net/yxw246/archive/2008/05/08/241 8255.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/star t
  三、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("document.domain='"+currentDomain+"';
  // -->");
  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-transpor t/
  常规来说,有以下方法:
  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) 和服务器交互。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics