论反向ajax

在议论反向ajax以前,说一下自家大二写的一个闲谈程序,通过前端ajax不断向服务器发送请求(通过http连接),服务器进行两遍数据库查询,然后再次来到结果,断开与服务器的链接(绝大多数都是无效的结果)来维持聊天界面的有的刷新,那种办法称为短链接轮询,对服务器造成的压力很大。

根据HTTP的长连接,是一种通过长轮询形式贯彻”服务器推”的技巧,它弥补了HTTP简单的伸手应对形式的不足,极大地增强了程序的实时性和交互性。

根据HTTP的长连接,是一种通过长轮询格局贯彻”服务器推”的技巧,它弥补了HTTP简单的呼吁应对方式的缺少,极大地拉长了程序的实时性和交互性。

依照HTTP的长连接,是一种通过长轮询格局贯彻”服务器推”的技巧,它弥补了HTTP不难的哀告应对形式的欠缺,极大地提升了程序的实时性和交互性。

前几日又用反向ajax写了一个随即聊天程序,通过长连接和ob缓存来兑现服务器到浏览器的数额传输,而那些长连接并不是想socket那样的坦途,它实质也是轮询。但是ajax就很懒,也很赖皮,每一遍来服务器家串门(检测是或不是有新新闻),都会耍嘴皮子的向服务器要多少(通过一个while死循环),直到服务器给了多少(满足了ajax的呼吁),这些请求才会回来浏览器。然后又卑鄙龌龊地来找服务器要多少服务器一遍次地给,xhr又三遍次地要。

 

 

一、什么是长连接、长轮询?

故而,ajax并不严酷意义上的长链接,只是比短链接长一些,每一趟请求完结实施回调时,在前三遍呼吁的功底上又随即展开一遍呼吁,除非设置了晚点;万一以此服务器很喜欢xhr,一要就给(当然那种气象是咱们很欢腾的,借此只是说贝拉米(Bellamy)下以此长连接的真面目),不就是个短链接嘛!

 

 

用通俗易懂的话来说,就是客户端不停的向服务器发送请求以获得最新的数目音信。那里的“不停”其实是有甘休的,只是大家人眼不可以辨识是或不是终止,它只是一种高效的停下然后又马上开首接二连三而已。

然后再说说我用反向ajax际遇的题材啊,我一个死不要脸的xhr请求(所谓的长连接,检测新信息)丢过去,等了半天也没影响,然后自己又丢了一个迷人的xhr小婴孩丢给服务器,可服务器并不以为那些小婴儿可爱,小婴儿送到服务器家门口服务器都不理。很显明之前的长连接阻塞了宝贝,但小婴儿是自个儿异步请求的,不应有是和长连接排在一个队呀!  

 

一、什么是长连接、长轮询?

二、长连接、长轮询的利用场景

解决办法:原来我新闻的发送者定义为$_SESSION[‘user’][‘nc’],在操作session时,会先经过session文件的处理,但是那一个长连接已经占了(此时session文件是会被php锁上的),首个session无法处理,就同样阻塞在服务器家门口咯!而开辟那扇们的钥匙,当然是关门session,在与服务器举办长连接时

一、什么是长连接、长轮询?

用通俗易懂的话来说,就是客户端不停的向服务器发送请求以获取最新的多寡音信。那里的“不停”其实是有为止的,只是大家人眼无法甄别是不是终止,它只是一种高效的告一段落然后又及时开首一而再而已。

长连接、长轮询一般拔取与WebIM、ChatRoom和一些急需立刻互动的网站接纳中。其真正案例有:WebQQ、Hi网页版、非死不可IM等。

设若您对服务器端的反向Ajax感兴趣,可以参考那篇小说 DWR 反向Ajax
服务器端推的办法:http://www.cnblogs.com/hoojo/category/276235.html

加上:session_write_close();问题成功解决。

用通俗易懂的话来说,就是客户端不停的向服务器发送请求以博得最新的数额新闻。那里的“不停”其实是有为止的,只是大家人眼不可能辨认是不是终止,它只是一种高效的停下然后又立马开始两次三番而已。

 

三、优缺点

澳门葡京备用网址 1

 

 

轮询:客户端定时向服务器发送Ajax请求,服务器收到请求后马上再次来到响应消息并关闭连接。

优点:后端程序编制比较易于。

症结:请求中有大约是无用,浪费带宽和服务器资源。

论反向ajax。实例:适于小型应用。

长轮询:客户端向服务器发送Ajax请求,服务器收到请求后hold住连接,直到有新音信才回到响应音信并关闭连接,客户端处理完响应信息后再向服务器发送新的哀告。

可取:在无音信的境况下不会反复的伸手,费用资源小。

缺陷:服务器hold连接会损耗资源,再次来到数据顺序无有限支撑,难于管理珍惜。

实例:WebQQ、Hi网页版、Facebook IM。

长连接:在页面里停放一个隐蔵iframe,将以此隐蔵iframe的src属性设为对一个长连接的哀告或是选拔xhr请求,服务器端就能继续不停地往客户端输入数据。

亮点:音讯即时到达,不发无用请求;管理起来也针锋相对有利。

症结:服务器维护一个长连接会增多支出。

实例:Gmail聊天

Flash Socket:在页面中内停放一个使用了Socket类的 Flash
程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口举办通讯,JavaScript在吸收服务器端传送的音信后决定页面的来得。

优点:已毕真正的即时通讯,而不是伪即时。

缺点:客户端必须安装Flash插件;非HTTP协议,不可能活动通过防火墙。

实例:网络互动娱乐。

另外PHP开发即时的程序最好用socket,搭配前端的websocket,真正实现了不断开的数据即时传输,目前windows系统php虽然提供了socket接口,但还没有真正的封装,需要自己编写socket类。如果计算机网络并不是太好,可以试着使用workman这个框架,它实现了socket的封装,并且有大量可扩展的
功能。

 

二、长连接、长轮询的应用场景

四、达成原理

 

 

长连接、长轮询一般选拔与WebIM、ChatRoom和局地亟待登时互动的网站使用中。其真实性案例有:WebQQ、Hi网页版、FacebookIM等。

借使你对劳务器端的反向Ajax感兴趣,可以参见这篇文章 DWR 反向Ajax
服务器端推的不二法门:

迎接大家继续扶助和关注自己的博客:

也欢迎我们和我调换、商量IT方面的学问。

email:hoojo_@126.com

所谓长连接,就是要在客户端与服务器之间创设和维系安澜可信的连接。其实它是一种很已经存在的技艺,可是由于浏览器技术的上进相比缓慢,没有为那种机制的兑现提供很好的支撑。所以要达标那种效益,要求客户端和服务器的主次共同同盟来形成。通常的做法是,在服务器的次序中参预一个死循环,在循环中监测数据的变更。当发现新数据时,马上将其出口给浏览器并断开连接,浏览器在接受数量后,再一次发起呼吁以进入下一个周期,这就是常说的长轮询(long-polling)形式。如下图所示,它常常包蕴以下多少个重点进程:

  1. 轮询的创建

确立轮询的进程很简单,浏览器发起呼吁后跻身循环等待状态,此时出于服务器还未做出答复,所以HTTP也直接处于连接意况中。

  1. 数量的推送

在循环进程中,服务器程序对数码变动举行监察,如发现更新,将该新闻输出给浏览器,随即断开连接,完毕应答进程,完结“服务器推”。

  1. 轮询的平息

轮询可能在偏下3种情景时停下:

3.1. 有新数据推送

当循环过程中服务器向浏览器推送新闻后,应该主动为止程序运行从而让连接断开,那样浏览器才能及时收到多少。

3.2. 尚无新数据推送

巡回无法直接不停下去,应该设定一个最长时限,防止WEB服务器超时(提姆(Tim)eout),若一向没有新新闻,服务器应积极向浏览器发送本次轮询无新新闻的例行响应,并断开连接,那也被称之为“心跳”新闻。

3.3. 网络故障或更加

出于网络故障等元素造成的请求超时或出错也可能导致轮询的不测中断,此时浏览器将收取错误音信。

  1. 轮询的重建

浏览器收到回复并开展对应处理后,应即时再度发起呼吁,伊始一个新的轮询周期。

二、长连接、长轮询的使用场景

 

五、程序设计

长连接、长轮询一般选用与WebIM、ChatRoom和一些索要及时互动的网站使用中。其忠实案例有:WebQQ、Hi网页版、FacebookIM等。

比方你对劳动器端的反向Ajax感兴趣,可以参照那篇文章 DWR 反向Ajax
服务器端推的不二法门: 

 

1、普通轮询 Ajax形式

 

三、优缺点

客户端代码片段

客户端完结的就是用一种普通轮询的结果,相比较容易。利用setInterval不间断的基础代谢来获得服务器的资源,那种措施的独到之处就是粗略、及时。缺点是链接多数是无用重复的;响应的结果尚未各类(因为是异步请求,当发送的请求没有回去结果的时候,后边的央浼又被发送。而这时倘使前边的乞求比前边的呼吁要先回来结果,那么当前边的呼吁重回结果数据时早已是老式无效的数额了);请求多,难于尊敬、浪费服务器和网络资源。

劳动器端代码

服务器端落成,这里就仿照下程序监控数据的转移。上边代码属于SpringMVC
中controller中的一个方法,约等于Servlet中的一个doPost/doGet方法。假若没有先后环境适应servlet即可,将方法体中的代码copy到servlet的doGet/doPost中即可。

劳务器端在拓展长连接的主次设计时,要注意以下几点:

1. 服务器程序对轮询的可控性

出于轮询是用死循环的点子完结的,所以在算法上要力保程序对什么日期退出循环有完全的控制能力,幸免进入死循环而耗尽服务器资源。

2. 创立采取“心跳”频率

从图1足以看出,长连接必须由客户端不停地拓展呼吁来有限支撑,所以在客户端和劳务器间保持正规的“心跳”至为关键,参数POLLING_LIFE应小于WEB服务器的超时时间,一般提议在10~20秒左右。

3. 网络因素的震慑

在其实使用时,从服务器做出回应,到下一次巡回的确立,是有时间推迟的,延迟时间的长短受网络传输等多种因素影响,在那段日子内,长连接处于暂时断开的空档,即使刚好有数据在那段时光内发出改变,服务器是不可能立刻举办推送的,所以,在算法设计上要留意化解由于延迟可能造成的数目丢失问题。

4. 服务器的性质

在长连接使用中,服务器与各种客户端实例都保持一个持久的连天,这将消耗大批量服务器资源,越发是在一些特大型应用系统中更是如此,大批量产出的长连接有可能引致新的呼吁被打断甚至系统崩溃,所以,在拓展程序设计时应尤其注意算法的优化和革新,必要时还索要考虑服务器的负荷均衡和集群技术。

上图是回来的结果,可以见见先发出请求,不自然会首先回到结果。这样就无法确保顺序,造成脏数据或无用的连接请求。可知对服务器或网络的资源浪费。

 

轮询:客户端定时向服务器发送Ajax请求,服务器收到请求后立刻赶回响应新闻并关闭连接。
优点:后端程序编制比较不难。
缺点:请求中有几乎是无用,浪费带宽和服务器资源。
实例:适于小型应用。

长轮询:客户端向服务器发送Ajax请求,服务器收到请求后hold住连接,直到有新音信才再次回到响应音讯并关闭连接,客户端处理完响应新闻后再向服务器发送新的央浼。
亮点:在无音信的情景下不会一再的请求,费用资源小。
缺点:服务器hold连接会开支资源,重临数据顺序无保险,难于管理有限协理。
实例:WebQQ、Hi网页版、Facebook IM。

长连接:在页面里放置一个隐蔵iframe,将以此隐蔵iframe的src属性设为对一个长连接的伸手或是采取xhr请求,服务器端就能接踵而至 蜂拥而至地往客户端输入数据。
优点:音信即时到达,不发无用请求;管理起来也绝对便宜。
缺点:服务器维护一个长连接会扩展花费。
实例:Gmail聊天

Flash Socket:在页面中内放置一个用到了Socket类的 Flash
程序JavaScript通过调用此Flash程序提供的Socket接口与劳动器端的Socket接口举办通讯,JavaScript在接到服务器端传送的新闻后控制页面的呈现。
可取:落成真正的即时通讯,而不是伪即时。
缺陷:客户端必须安装Flash插件;非HTTP协议,无法自行通过防火墙。
实例:网络互动游戏。

2、普通轮询 iframe格局

三、优缺点

 

此地的客户端程序是行使隐藏的iframe向服务器端不停的拉取数据,将iframe获取后的数据填充到页面中即可。同ajax完结的基本原理一样,唯一差别的是当一个伸手没有响应再次来到数据的情景下,下一个请求也将伊始,那时候前边的呼吁将被截至。借使要使程序和地点的ajax请求一样也足以办到,那就是给各类请求分配一个独自的iframe即可。下边是回到的结果:

其间紫色是从未中标重返请求就被终止(前面请求开端)掉的哀求,蓝色是成功再次回到数据的央求。

轮询:客户端定时向服务器发送Ajax请求,服务器收到请求后立刻赶回响应新闻并关闭连接。 
可取:后端程序编制比较不难。 
缺点:请求中有差不离是无用,浪费带宽和服务器资源。 
实例:适于小型应用。

长轮询:客户端向服务器发送Ajax请求,服务器收到请求后hold住连接,直到有新信息才重回响应新闻并关闭连接,客户端处理完响应音讯后再向服务器发送新的伸手。 
亮点:在无音信的气象下不会一再的哀告,用度资源小。 
缺点:服务器hold连接会消耗资源,重返数据顺序无有限接济,难于管理维护。 
实例:WebQQ、Hi网页版、Facebook IM。

 

长连接:在页面里停放一个隐蔵iframe,将以此隐蔵iframe的src属性设为对一个长连接的乞请或是采取xhr请求,服务器端就能源源不断地往客户端输入数据。 
可取:音信即时到达,不发无用请求;管理起来也针锋绝对有利。 
症结:服务器维护一个长连接会追加支出。 
实例:Gmail聊天

Flash Socket:在页面中内放置一个使用了Socket类的 Flash
程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通讯,JavaScript在接收服务器端传送的新闻后控制页面的显得。 
亮点:落成真正的即时通讯,而不是伪即时。 
症结:客户端必须安装Flash插件;非HTTP协议,不可以自动通过防火墙。 
实例:网络互动娱乐。

 

3、长连接iframe方式

 

四、已毕原理

这些轮询格局就是把刚刚上边的有点改下,每个请求都有和好独立的一个iframe,当那么些iframe拿到响应的多少后就把数量push到当下页面上。使用此方法已经接近于ajax的异步交互了,那种办法也是无法担保顺序的、相比费用资源、而且连接有一个加载的条在位置栏或状态栏附件(当然要缓解可以使用htmlfile,谷歌的攻城师们已经成功了,网上也有包装好的lib库),但客户端完成起来相比不难。

假如要有限支撑平稳,可以不利用setInterval,将创造iframe的法子放在load事件中即可,即利用递归形式。调整后的代码片段如下:

那种艺术即便有限支撑了请求的逐条,可是它不会处理请求延时的谬误可能说很长日子没有回来结果的哀告,它会一直等到再次回到请求后才能创建下一个iframe请求,总会和服务器保持一个两次三番。和上述轮询相比,缺点就是音讯不即刻,但保证了请求的一一。

 


谓长连接,就是要在客户端与服务器之间成立和有限协助安澜可信的连日。其实它是一种很已经存在的技艺,可是由于浏览器技术的升华相比较缓慢,没有为那种机制的达成提供很好的支持。所以要达标那种成效,要求客户端和服务器的次第共同协作来成功。平时的做法是,在服务器的程序中参加一个死循环,在循环中监测数据的变
动。当发现新数据时,立刻将其出口给浏览器并断开连接,浏览器在接到多少后,再次发起呼吁以进入下一个周期,那就是常说的长轮询(long-
polling)方式。如下图所示,它常常包含以下多少个关键进度:

澳门葡京备用网址 2

  1. 轮询的创制
    确立轮询的经过很粗略,浏览器发起呼吁后跻身循环等待状态,此时由于服务器还未做出答复,所以HTTP也直接处于连接意况中。
  2. 数量的推送
    在循环进度中,服务器程序对数据变动举办监察,如察觉更新,将该音讯输出给浏览器,随即断开连接,完毕应答进度,完成“服务器推”。
  3. 轮询的告一段落
    轮询可能在偏下3种景况时停下:
      3.1. 有新数据推送
      
    当循环过程中服务器向浏览器推送信息后,应该主动截至程序运行从而让连接断开,那样浏览器才能及时吸纳数额。
      3.2. 并未新数据推送
      
    循环无法直接不绝于耳下去,应该设定一个最长时限,防止WEB服务器超时(提姆(Tim)eout),若间接没有新音信,服务器应主动向浏览器发送这一次轮询无新新闻的正规响应,并断开连接,那也被称呼“心跳”消息。
      3.3. 网络故障或更加
      
    由于网络故障等要素促成的哀求超时或出错也说不定造成轮询的奇怪中断,此时浏览器将吸纳错误信息。
  4. 轮询的重建
    浏览器收到回复并开展对应处理后,应即刻再度发起呼吁,开头一个新的轮询周期。

4、ajax已毕长连接

 

 

地点那段代码就是才有Ajax的法门成就长连接,主要优点就是和服务器始终维持一个连连。如若当前连连请求成功后,将更新数据同时继续创制一个新的连年和服务器保持联系。如果两次三番超时或爆发万分,那一个时候程序也会创设一个新连接继续呼吁。那样就大大节省了服务器和网络资源,升高了程序的性能,从而也确保了先后的次第。

四、已毕原理

五、程序设计

所谓长连接,就是要在客户端与服务器之间创制和维持安静可相信的连接。其实它是一种很已经存在的技艺,可是出于浏览器技术的前进相比较缓慢,没有为那种体制的兑现提供很好的支撑。所以要完毕那种效益,要求客户端和服务器的先后共同协作来形成。经常的做法是,在服务器的次序中参预一个死循环,在循环中监测数据的改动。当发现新数据时,马上将其出口给浏览器并断开连接,浏览器在收到多少后,再一次发起呼吁以进入下一个周期,那就是常说的长轮询(long-polling)格局。如下图所示,它经常包涵以下多少个重大进度:

澳门葡京备用网址 3

  1. 轮询的创制 
    确立轮询的长河很粗略,浏览器发起呼吁后进入循环等待景况,此时出于服务器还未做出回复,所以HTTP也间接处于连接情形中。 
  2. 数量的推送 
    在循环进程中,服务器程序对数据变动进行监察,如发现更新,将该音信输出给浏览器,随即断开连接,完结应答过程,落成“服务器推”。 
  3. 轮询的终止 
    轮询可能在偏下3种状态时停下: 
      3.1. 有新数据推送 
      
    当循环进度中服务器向浏览器推送音讯后,应该主动停止程序运行从而让连接断开,这样浏览器才能及时收到多少。 
      3.2. 从未有过新数据推送 
      
    循环无法直接不停下去,应该设定一个最长时限,幸免WEB服务器超时(提姆(Tim)eout),若直接没有新音信,服务器应积极向浏览器发送本次轮询无新新闻的例行响应,并断开连接,那也被称作“心跳”音讯。 
      3.3. 网络故障或尤其 
      
    由于网络故障等元素造成的乞请超时或出错也可能导致轮询的竟然中断,此时浏览器将吸纳错误音讯。 
  4. 轮询的重建 
    浏览器收到回复并开展对应处理后,应立即再一次发起呼吁,开始一个新的轮询周期。

1、普通轮询 Ajax形式

六、总结

 

客户端代码片段

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                

                    $.get("${pageContext.request.contextPath}/communication/user/ajax.mvc", 

                        {"timed": new Date().getTime()}, 

                        function (data) {

                            $("#logs").append("[data: " + data + " ]<br/>");

                    });

                }, 3000);

                

            });

        </script>

    </head>

    

    <body>

        <div id="logs"></div>

    </body>

</html>

客户端完毕的就是用一种家常轮询的结果,相比不难。利用setInterval不间断的刷新来得到服务器的资源,这种形式的助益就是不难、
及时。缺点是链接多数是低效重复的;响应的结果没有各样(因为是异步请求,当发送的哀告没有回来结果的时候,前边的呼吁又被发送。而此时只要前边的伸手比
前边的伸手要先重返结果,那么当前边的请求再次来到结果数据时曾经是不合时宜无效的数额了);请求多,难于爱戴、浪费服务器和网络资源。

劳务器端代码

@RequestMapping("/ajax")

public void ajax(long timed, HttpServletResponse response) throws Exception {

     PrintWriter writer = response.getWriter();

     

     Random rand = new Random();

     // 死循环 查询有无数据变化

     while (true) {

         Thread.sleep(300); // 休眠300毫秒,模拟处理业务等

         int i = rand.nextInt(100); // 产生一个0-100之间的随机数

         if (i > 20 && i < 56) { // 如果随机数在20-56之间就视为有效数据,模拟数据发生变化

             long responseTime = System.currentTimeMillis();

             // 返回数据信息,请求时间、返回数据时间、耗时

             writer.print("result: " + i + ", response time: " + responseTime + ", request time: " + timed + ", use time: " + (responseTime - timed));

             break; // 跳出循环,返回数据

         } else { // 模拟没有数据变化,将休眠 hold住连接

             Thread.sleep(1300);

         }

     }

     

}

劳动器端完成,那里就模仿下程序监控数据的变化。上边代码属于SpringMVC
中controller中的一个方式,相当于Servlet中的一个doPost/doGet方法。假若没有先后环境适应servlet即可,将方法体中
的代码copy到servlet的doGet/doPost中即可。

** style=”color: #ff0000;”>服务器端在开展长连接的次序设计时,要留心以下几点:

  1. 服务器程序对轮询的可控性
    出于轮询是用死循环的法门贯彻的,所以在算法上要保管程序对什么时候退出循环有一齐的控制能力,幸免进入死循环而耗尽服务器资源。
    2. 客观选用“心跳”频率
    从图1方可看看,长连接必须由客户端不停地举办呼吁来保持,所以在客户端和劳动器间保持正常的“心跳”至为关键,参数POLLING_LIFE应小于WEB服务器的过期时间,一般提出在10~20秒左右。 3. 网络因素的影响
    在实际上利用时,从服务器做出回复,到下一次巡回的树立,是有时间推移的,延迟时间的长短受网络传输等多种因素
    影响,在那段时间内,长连接处于暂时断开的空档,若是正好有数据在那段日子内发出变动,服务器是力不从心即时进行推送的,所以,在算法设计上要小心解决由于延
    迟可能造成的数据丢失问题。
    4. 服务器的习性**
    在长连接使用中,服务器与每个客户端实例都保持一个绳锯木断的连接,那将消耗大批量服务器资源,更加是在一些特大型应用系统中更是如此,多量并发的长连接有可能造成新的请求被打断甚至系统崩溃,所以,在进展程序设计时应尤其注意算法的优化和革新,须求时还亟需考虑服务器的负荷均衡和集群技术。

澳门葡京备用网址 4

上图是回来的结果,可以见见头阵出请求,不肯定会首先回到结果。这样就无法保障顺序,造成脏数据或无用的连接请求。可知对服务器或网络的资源浪费。

现代的浏览器都辅助跨域资源共享(Cross-Origin Resource
Share,CORS)规范,该专业允许XHR执行跨域请求,因而根据脚本的和依照iframe的技能已变成了一种过时的内需。

把Comet做为反向Ajax的落到实处和选拔的最好法子是通过XMLHttpRequest对象,该做法提供了一个的确的连日句柄和错误处理。当然你挑选经过HTTP长轮询使用XMLHttpRequest对象(在劳务器端挂起的一个粗略的Ajax请求)的Comet形式,所有接济Ajax的浏览器也都援助该种做法。

据悉HTTP的长连接技术,是近期在纯浏览器环境下进行及时交互类应用开发的能够选择,随着浏览器的快捷发展,html5将为其提供更好的支撑和更宽泛的选拔。在html5中有一个websocket
可以很和谐的形成长连接这一技能,网上也有有关地点的素材,那里也就不再做过多介绍。

 

2、普通轮询 iframe方式

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                    $("#logs").append("[data: " + $($("#frame").get(0).contentDocument).find("body").text() + " ]<br/>");

                    $("#frame").attr("src", "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime());

                    // 延迟1秒再重新请求

                    window.setTimeout(function () {

                        window.frames["polling"].location.reload();

                    }, 1000);

                }, 5000);

                

            });

        </script>

    </head>

    

    <body>

        <iframe id="frame" name="polling" style="display: none;"></iframe>

        <div id="logs"></div>

    </body>

</html>

此处的客户端程序是利用隐藏的iframe向劳动器端不停的拉取数据,将iframe获取后的数额填充到页面中即可。同ajax完结的基本
原理一样,唯一不相同的是当一个伸手没有响应再次来到数据的图景下,下一个呼吁也将启幕,那时候前边的乞请将被截止。借使要使程序和上面的ajax请求一样也可以办到,那就是给种种请求分配一个独门的iframe即可。上边是回来的结果:

澳门葡京备用网址 5

其间青色是不曾马到功成再次来到请求就被终止(前面请求开头)掉的请求,肉色是成功再次来到数据的乞请。

五、程序设计

3、长连接iframe方式

1、普通轮询 Ajax形式

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                    var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();

                    var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');

                    $("body").append($iframe);

                

                    $iframe.load(function () {

                        $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");

                        $iframe.remove();

                    });

                }, 5000);

                

            });

        </script>

    </head>

    

    <body>

        

        <div id="logs"></div>

    </body>

</html>

以此轮询形式就是把刚刚方面的多少改下,每个请求都有和好独自的一个iframe,当那几个iframe获得响应的多少后就把数据push到
当前页面上。使用此措施已经接近于ajax的异步交互了,那种办法也是不能担保顺序的、相比较费用资源、而且连接有一个加载的条在地点栏或情形栏附件(当然
要解决可以动用htmlfile,谷歌的攻城师们已经做到了,网上也有包装好的lib库),但客户端达成起来相比较简单。

 澳门葡京备用网址 6

借使要保管平稳,可以不接纳setInterval,将成立iframe的法子放在load事件中即可,即利用递归情势。调整后的代码片段如下:

<script type="text/javascript">

    $(function () {

        (function iframePolling() {

            var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();

            var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');

            $("body").append($iframe);

        

            $iframe.load(function () {

                $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");

                $iframe.remove();

                

                // 递归

                iframePolling();

            });

        })();    

    });

</script>

那种方法尽管保障了请求的逐条,但是它不会处理请求延时的一无可取可能说很长日子从没回来结果的呼吁,它会一贯等到再次来到请求后才能创设下一个iframe请求,总会和服务器保持一个连接。和上述轮询相比,缺点就是新闻不立刻,但有限援救了请求的一一。

客户端代码片段

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                

                    $.get("${pageContext.request.contextPath}/communication/user/ajax.mvc", 

                        {"timed": new Date().getTime()}, 

                        function (data) {

                            $("#logs").append("[data: " + data + " ]<br/>");

                    });

                }, 3000);

                

            });

        </script>

    </head>

    

    <body>

        <div id="logs"></div>

    </body>

</html>

 

客户端完成的就是用一种平日轮询的结果,比较不难。利用setInterval不间断的刷新来获得服务器的资源,那种情势的助益就是概括、及时。缺点是链接多数是不行重复的;响应的结果尚未种种(因为是异步请求,当发送的伏乞没有重回结果的时候,前面的呼吁又被发送。而那时候若是后面的伸手比前边的伸手要先回去结果,那么当前边的请求再次来到结果数据时一度是老式无效的数码了);请求多,难于爱戴、浪费服务器和网络资源。

 

劳务器端代码

 

 

@RequestMapping("/ajax")

public void ajax(long timed, HttpServletResponse response) throws Exception {

     PrintWriter writer = response.getWriter();

     

     Random rand = new Random();

     // 死循环 查询有无数据变化

     while (true) {

         Thread.sleep(300); // 休眠300毫秒,模拟处理业务等

         int i = rand.nextInt(100); // 产生一个0-100之间的随机数

         if (i > 20 && i < 56) { // 如果随机数在20-56之间就视为有效数据,模拟数据发生变化

             long responseTime = System.currentTimeMillis();

             // 返回数据信息,请求时间、返回数据时间、耗时

             writer.print("result: " + i + ", response time: " + responseTime + ", request time: " + timed + ", use time: " + (responseTime - timed));

             break; // 跳出循环,返回数据

         } else { // 模拟没有数据变化,将休眠 hold住连接

             Thread.sleep(1300);

         }

     }

     

}

 

 

劳动器端已毕,那里就仿照下程序监控数据的变化。上边代码属于SpringMVC
中controller中的一个主意,相当于Servlet中的一个doPost/doGet方法。即使没有先后环境适应servlet即可,将方法体中的代码copy到servlet的doGet/doPost中即可。

 

** style=”color: #ff0000;”>服务器端在开展长连接的顺序设计时,要留心以下几点: 

  1. 服务器程序对轮询的可控性 
    出于轮询是用死循环的办法贯彻的,所以在算法上要力保程序对几时退出循环有完全的控制能力,幸免进入死循环而耗尽服务器资源。 
    2. 创造选用“心跳”频率 
    从图1足以看来,长连接必须由客户端不停地拓展呼吁来保险,所以在客户端和劳动器间保持正常的“心跳”至为关键,参数POLLING_LIFE应小于WEB服务器的过期时间,一般指出在10~20秒左右。  3. 网络因素的熏陶 
    在事实上使用时,从服务器做出回答,到下三遍巡回的成立,是有时光推移的,延迟时间的长短受网络传输等多种元素影响,在那段时光内,长连接处于暂时断开的空档,即使正好有多少在那段时日内发出变更,服务器是力不从心即时进行推送的,所以,在算法设计上要小心化解由于延迟可能造成的多寡丢失问题。  4. 服务器的习性** 
    在长连接使用中,服务器与各样客户端实例都维持一个锲而不舍的接连,那将花费大批量服务器资源,越发是在一些重型应用连串中更是如此,大批量并发的长连接有可能造成新的央浼被打断甚至系统崩溃,所以,在开展程序设计时应尤其注意算法的优化和核查,须要时还亟需考虑服务器的载重均衡和集群技术。

澳门葡京备用网址 7

上图是回来的结果,可以看看先发出请求,不肯定会首先回到结果。那样就不可以有限匡助顺序,造成脏数据或无用的接连请求。可知对服务器或网络的资源浪费。

4、ajax完结长连接

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                (function longPolling() {

                

                    $.ajax({

                        url: "${pageContext.request.contextPath}/communication/user/ajax.mvc",

                        data: {"timed": new Date().getTime()},

                        dataType: "text",

                        timeout: 5000,

                        error: function (XMLHttpRequest, textStatus, errorThrown) {

                            $("#state").append("[state: " + textStatus + ", error: " + errorThrown + " ]<br/>");

                            if (textStatus == "timeout") { // 请求超时

                                    longPolling(); // 递归调用

                                

                                // 其他错误,如网络错误等

                                } else { 

                                    longPolling();

                                }

                            },

                        success: function (data, textStatus) {

                            $("#state").append("[state: " + textStatus + ", data: { " + data + "} ]<br/>");

                            

                            if (textStatus == "success") { // 请求成功

                                longPolling();

                            }

                        }

                    });

                })();

                

            });

        </script>

    </head>

    

    <body>

地方那段代码就是才有Ajax的不二法门完结长连接,首要优点就是和服务器始终维持一个一而再。假设当前连年请求成功后,将立异数据同时一连创建一个新的总是和服务器保持联系。假使连续超时或暴发尤其,那一个时候程序也会创建一个新连接继续呼吁。那样就大大节约了服务器和网络资源,进步了先后的性
能,从而也有限支撑了程序的逐一。

澳门葡京备用网址 8

2、普通轮询 iframe格局

 

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                    $("#logs").append("[data: " + $($("#frame").get(0).contentDocument).find("body").text() + " ]<br/>");

                    $("#frame").attr("src", "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime());

                    // 延迟1秒再重新请求

                    window.setTimeout(function () {

                        window.frames["polling"].location.reload();

                    }, 1000);

                }, 5000);

                

            });

        </script>

    </head>

    

    <body>

        <iframe id="frame" name="polling" style="display: none;"></iframe>

        <div id="logs"></div>

    </body>

</html>

 

澳门葡京备用网址,此地的客户端程序是行使隐藏的iframe向劳动器端不停的拉取数据,将iframe获取后的数量填充到页面中即可。同ajax落成的基本原理一样,唯一不一致的是当一个请求没有响应再次来到数据的场馆下,下一个伸手也将初叶,那时候前面的呼吁将被终止。假使要使程序和方面的ajax请求一样也得以办到,那就是给各样请求分配一个独自的iframe即可。下边是回来的结果:

澳门葡京备用网址 9

里面灰色是不曾马到功成再次来到请求就被终止(后边请求发轫)掉的央求,粉灰色是成功再次来到数据的央浼。

六、总结

 

现代的浏览器都帮衬跨域资源共享(Cross-Origin Resource
Share,CORS)规范,该专业允许XHR执行跨域请求,因而根据脚本的和根据iframe的技艺已变成了一种过时的内需。

把Comet做为反向Ajax的兑现和应用的最好办法是透过XMLHttpRequest对象,该做法提供了一个实在的接连句柄和错误处
理。当然你挑选经过HTTP长轮询使用XMLHttpRequest对象(在劳务器端挂起的一个不难的Ajax请求)的Comet形式,所有支持Ajax
的浏览器也都援救该种做法。

依据HTTP的长连接技术,是当下在纯浏览器环境下展开即时交互类应用开发的地道选用,随着浏览器的很快发展,html5将为其提供更好的
接济和更广阔的利用。在html5中有一个websocket
可以很投机的做到长连接这一技术,网上也有相关方面的素材,那里也就不再做过多介绍。

3、长连接iframe方式

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                window.setInterval(function () {

                    var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();

                    var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');

                    $("body").append($iframe);

                

                    $iframe.load(function () {

                        $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");

                        $iframe.remove();

                    });

                }, 5000);

                

            });

        </script>

    </head>

    

    <body>

        

        <div id="logs"></div>

    </body>

</html>

 

 

其一轮询格局就是把刚刚地点的有点改下,每个请求都有谈得来独立的一个iframe,当以此iframe得到响应的数量后就把数据push到近期页面上。使用此方法已经八九不离十于ajax的异步交互了,那种艺术也是无法确保顺序的、比较花费资源、而且接二连三有一个加载的条在地点栏或景况栏附件(当然要解决可以行使htmlfile,谷歌(Google)的攻城师们已经完成了,网上也有包装好的lib库),但客户端已毕起来相比较不难。

 澳门葡京备用网址 10

要是要力保平稳,可以不应用setInterval,将成立iframe的不二法门放在load事件中即可,即采纳递归方式。调整后的代码片段如下:

 

 

<script type="text/javascript">

    $(function () {

        (function iframePolling() {

            var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();

            var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');

            $("body").append($iframe);

        

            $iframe.load(function () {

                $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");

                $iframe.remove();

                

                // 递归

                iframePolling();

            });

        })();    

    });

</script>

 

 

 

 

 

 

 

那种办法纵然保障了请求的一一,不过它不会处理请求延时的不当可能说很长日子没有回去结果的伸手,它会向来等到再次来到请求后才能制造下一个iframe请求,总会和服务器保持一个总是。和上述轮询比较,缺点就是音信不立刻,但有限援救了请求的顺序。

 

4、ajax完结长连接

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <%@ include file="/tags/jquery-lib.jsp"%>

        

        <script type="text/javascript">

            $(function () {

            

                (function longPolling() {

                

                    $.ajax({

                        url: "${pageContext.request.contextPath}/communication/user/ajax.mvc",

                        data: {"timed": new Date().getTime()},

                        dataType: "text",

                        timeout: 5000,

                        error: function (XMLHttpRequest, textStatus, errorThrown) {

                            $("#state").append("[state: " + textStatus + ", error: " + errorThrown + " ]<br/>");

                            if (textStatus == "timeout") { // 请求超时

                                    longPolling(); // 递归调用

                                

                                // 其他错误,如网络错误等

                                } else { 

                                    longPolling();

                                }

                            },

                        success: function (data, textStatus) {

                            $("#state").append("[state: " + textStatus + ", data: { " + data + "} ]<br/>");

                            

                            if (textStatus == "success") { // 请求成功

                                longPolling();

                            }

                        }

                    });

                })();

                

            });

        </script>

    </head>

    

    <body>

 

下边那段代码就是才有Ajax的格局形成长连接,首要优点就是和服务器始终维持一个连连。如若当前连日请求成功后,将革新数据同时一连开创一个新的连日和服务器保持联系。如若老是超时或爆发尤其,这几个时候程序也会创立一个新连接继续呼吁。那样就大大节约了服务器和网络资源,升高了程序的属性,从而也确保了先后的相继。

澳门葡京备用网址 11

 

六、总结

当代的浏览器都支持跨域资源共享(Cross-Origin Resource
Share,CORS)规范,该专业允许XHR执行跨域请求,由此根据脚本的和依照iframe的技巧已改为了一种过时的内需。

把Comet做为反向Ajax的落到实处和使用的最好措施是通过XMLHttpRequest对象,该做法提供了一个确实的三番五次句柄和错误处理。当然你挑选经过HTTP长轮询使用XMLHttpRequest对象(在服务器端挂起的一个粗略的Ajax请求)的Comet形式,所有协理Ajax的浏览器也都援助该种做法。

基于HTTP的长连接技术,是时下在纯浏览器环境下进行当下交互类使用开发的名特优选拔,随着浏览器的很快升高,html5将为其提供更好的扶助和更宽广的采用。在html5中有一个websocket
可以很融洽的落成长连接这一技术,网上也有有关地点的资料,那里也就不再做过多介绍。

 

 

来源:

  Web 通信 之 长连接、长轮询(long
polling)

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website