首页客户案例高端网站建设SEO优化小程序开发APP定制开发网络营销关于我们动态联系咨询

Web通信之:数据流(streaming)

  昨天说了长轮询(long-polling),我们把它比作是了一群人在排队上厕所。被这么多人轮着上,厕所都累了!今天要说的数据流就比较轻松,它没有那样长长的队伍,只有一人、一厕。而且这个人在厕所里一呆就是很久的,不会像长轮询那样一直进进出出。但是服务器是轻松了,开发人员就累了。   数据流通信,实际上即使和服务器建立一个HTTP连接,然后不断开,服务器只要一直通过那个连接发送数据就可以了。这个方法在兼容性上可不是那么容易搞定的。如果是用XHR对象做传输媒介,能完美兼容的只有Chrome和FireFox。Opera下XHR对象接收到数据不会产生事件,需要用一个计时器去判断是否收到数据。在IE下读取中的XHR对象根本就无法操作,所以在IE下我们必须找到其它方法来替代它。这就是使用IFRAME作为IE的传输媒介的方法,因为IFRAME在传输过程中,数据是可以被读出来的。接着又会遇上一个问题,如果使用IFRAME,浏览器会一直保持在加载状态。这就意味着,网页的图标会一直保持等待图标。这样当然不好,所以我们用了另一种手段让IFRAME加载的时候在IE中不显示加载状态。IE中支持HTMLFile对象,这个对象就相当于一个内存中的Document对象,它会解析文档。所以我们创建一个HTMLFile对象,在里面放置一个IFRAME来连接服务器。这样,各种浏览器就都支持了。现在我们来看代码,为了方便测试,服务器程序的代码我就写成了简单的每秒输出当期时间的程序。下面是代码   接着是前端的代码,由于IE和其它浏览器的实现原理不同,所以代码会有点长,不过我都做了比较详细的注释,理解起来也不会太困难。 //获取浏览器信息 var isIE=navigator.userAgent.match(/MSIE (\d)/); isIE=isIE?isIE[1]:undefined; var isOpera=/Opera/.test(navigator.userAgent);

//设置参数 var url,splitchar; url="test.php"; splitChar=String.fromCharCode(1);

//判断浏览器 if(isIE) //如果是IE则使用这种方法 (function(){ var doc,ifr,itv,o,f; //保存当前函数 f=arguments.callee; //创建HTMLFile对象 doc=new ActiveXObject("HTMLFile"); //在HTMLFile中创建BODY doc.write("") //创建IFRAME ifr=doc.createElement("iframe"); //IFRAME的连接到服务器的地址 ifr.src=url; //把IFRAME放入HTMLFile的BODY中 doc.body.appendChild(ifr); //获取IFRAME中的document对象 o=ifr.contentWindow.document; //创建计时器,循环从IFRAME中读取数据 itv=setInterval(function(){ //判断IFRAME的状态 switch(ifr.readyState){ case "interactive"://读取数据时 var i,s; //把服务器返回的数据取出 s=o.body.innerHTML; //分割数据,然后循环并操作数据 s=s.split(splitChar); for(i in s)if(s[i])ReceivedData(s[i]); //清空IFRAME接收到的数据 o.body.innerHTML=""; break; case "complete"://服务器断开连接时 //关闭计时器 clearInterval(itv); //调用当前函数重新连接服务器 f(); }; },1000); })(); else //如果非IE则使用这种方法 (function(){ var xhr,f,p; //保存当前函数 f=arguments.callee; //创建XHR对象 xhr=new XMLHttpRequest; //设置数据游标 //由于服务器一开始会发送1KB的数据 //所以此处从1024开始 p=1024; //添加爱XHR读取状态改变的事件 xhr.onreadystatechange=function(){ switch(xhr.readyState){ case 3://正在读取数据 var i,l,s; //读取数据 s=xhr.response; //获取数据长度 l=s.length; //从游标位置开始获取数据,并用分割数据 s=s.slice(p,l-1).split(splitChar); //循环并操作数据 for(i in s)if(s[i])ReceivedData(s[i]); //更新游标位置 p=l; //如果缓冲区占太多内存则断开连接 if(l>10485760)xhr.abort(); break; case 4://与服务器断开 //重新连接 setTimeout(f,1000); }; }; isOpera&&(function(){ xhr.onreadystatechange(); setTimeout(arguments.callee,1000); })(); //设置连接参数 xhr.open("GET",url,true); //连接服务器 xhr.send(); })();

//收到数据后执行的函数 function ReceivedData(e){ //把数据输出到BODY中 var div=document.createElement("div"); div.appendChild(document.createTextNode(e)); document.body.appendChild(div); };   在IE中为了方法我直接使用了innerHTML来读取,简单的数据可以使用这种方式。不过如果需要输出更复杂的数据就需要自己组织好HTML了,或者把该转义的都转义了也行。其它浏览器中要注意的就是内存,因为XHR对象在连接状态下内存是不能释放的,所以如果需要优化应该往这方面优化。   数据流的方法是目前HTTP通信中最节省服务器资源的了。如果非要使用HTTP协议开发大型即时通信程序,就可以使用这个方法。当然我更推荐使用AS直接与服务器TCP通信的方法。 本文来源于广州网站建设公司与广州网站设计制作公司-中网赢通广州公司!

日期:2015年05月20日

标签: 广州网站设计公司 、 广州网站设计 、 广州网站建设公司 、 广州网站建设 、 广州网站制作公司 、 广州网站制作 、 高端网站设计 、 高端网站建设 、 广州高端网站设计 、 广州高端网站建设

获取您的项目定制及优化报价。

* 为广州天河、白云、海珠、番禺、花都、南沙区提供互联网技术服务。
线上服务咨询微信二维码13609002706免费获取诊断报告