框架基础:ajax设计方案(二)---集成轮询技术

上一篇文章介绍了ajax技术核心方法,和跨域的问题(只要后台支持跨域默认post就可以),这篇文章讲解一下使用ajax实现的轮询技术,至于iframe,SSE服务器单向推送,以及webSocket双工通道暂时不涉及

一些概念:

  短轮询:浏览器通过循环或者setTimeout方法,每隔一段时间往后台发送一次请求,无线循环

  长轮询:不停的向后台请求数据,但是后台如果检测不到数据变动,就会将这个请求挂掉。如果检测到数据变动,就会响应这个请求变动数据

区别概念:

  长连接:在进行http数据传输的时候,在数据传输层一直开着一个TCP通道,所有请求资源文件都是通过复用这个通道去请求数据,有超时时间

  短连接:如果http进行的短连接,即每次浏览器发送请求,都会创建TCP通道,然后传输完成了再进行销毁,重复操作,消耗很大

主要区别:

  1. http的长短轮询,通过代码层,向后台请求数据。
  2. Http的长短连接,实际上就是TCP协议传输层是否复用一个TCP协议。

主要业务方面:及时性比较高的应用(web端聊天系统),或者需要后台等待响应的应用(比如付款,等待完成响应)。

关键代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

/*

    * 长轮询的实现

    *   a. 业务上只需要得到服务器一次响应的轮询

    *   b. 业务上需要无限次得到服务器响应的轮询

    *

    *   param: url   请求接口地址

    *          data  请求参数

    *          successEvent    成功事件处理

    *          isAll           是否一直请求(例如,等待付款完成业务,只需要请求一次)

    *          timeout         ajax超时时间

    *          timeFrequency   每隔多少时间发送一次请求

    *          error           错误事件

    *          timeout         超时处理

    * */

   longPolling:function(url,data,successEvent,isAll,timeout,timeFrequency,errorEvent,timeoutEvent){

       var ajaxParam ={

           time:timeout,

           type:"post",

           url:url,

           data:data,

           async:false,

           success:function(date){

               successEvent(data);

               var timer = setTimeout(

                   function(){

                       tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent);

                   },timeFrequency);

               //业务需求判断,是否只需要得到一次结果

               if (!isAll) clearTimeout(timer);

           },

           //如果走了error说明该接口有问题,没必要继续下去了

           error:errorEvent,

           timeout:function(){

               timeoutEvent();

               setTimeout(function(){

                   tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent)

               },timeFrequency);

           }

       };

       ajax.common(ajaxParam);

   }

考虑到业务需求,集成了一次isAll参数有2个意义

  1. 聊天系统会要一直需求轮询,不间断的向后台使用数据,所以isAll = true
  2. 等待付款业务只需要得到后台一次响应是否支付成功,所以isAll = false

稍微提及一下遇到的一些问题:

问题:


1

2

3

4

success:function(date){

     successEvent(data);    //此处使用递归,不停递归自己

     tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent);

},       

浏览器报错:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

Uncaught RangeError: Maximum call stack size exceeded.

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

    at Object.success (ajax-1.2.js:266)

    at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

    at Object.success (ajax-1.2.js:266)

    at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

common @ ajax-1.2.js:202

longPolling @ ajax-1.2.js:280

success @ ajax-1.2.js:266

xhr.onload @ ajax-1.2.js:160

(anonymous) @ index.html:42

(anonymous) @ index.html:43

ajax-1.2.js:202 Uncaught RangeError: Maximum call stack size exceeded.

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

    at Object.success (ajax-1.2.js:266)

    at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

    at Object.success (ajax-1.2.js:266)

    at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)

    at Object.common (ajax-1.2.js:202)

    at Object.longPolling (ajax-1.2.js:280)

英文解释:

超出最大调用堆栈大小。

问题原因:

递归调用过多导致的栈溢出问题说明

问题解释:

函数调用的参数是通过栈空间来传递的,在调用过程中会占用线程的栈资源。而递归调用,只有走到最后的结束点后函数才能依次退出,而未到达最后的结束点之前,占用的栈空间一直没有释放,如果递归调用次数过多,就可能导致占用的栈资源超过线程的最大值,从而导致栈溢出,导致程序的异常退出。js可以调用自身,这里不停的调用longPolling方法,在方法里面不停的调用自己,导致GC(垃圾回收)一直不释放,越来越大,导致资源超过最大上限,直接崩溃。然后级联一层一层的抛出崩溃信息

解决方案:

使用settimeout解决该问题

方案解释:

因为Javascript是单线程的,有个排队的处理队列,所以settimeout相当于有一个计时器,不停的向这个队列每隔一段时间塞进一个处理事件。因为这样,相当于longPolling方法每次都走完了,GC就将该方法的资源释放了,然后再执行,再释放。

代码已集成github:https://github.com/GerryIsWarrior/ajax     点颗星星是我最大的鼓励,下一步研究ajax的上传文件技术(H5的)

PS:对于轮询这个技术,虽然平时用的少,但是在一些特殊的业务场景能发挥很大的作用。在浏览器,没有完完全全支持H5的境况下,这个还是要考虑的。毕竟H5的那些webSocket还是需要H5兼容的。而且,研究这一块,对原声js,和计算机的一些底层技术还是很有帮助的,像堆栈溢出,不仅仅是前端,后端也会遇到。这样的话,自己底层更夯实,对于以后上层的发展也会有更好的增长。

【转发自http://www.cnblogs.com/GerryOfZhong/p/6135288.html】

时间: 2024-10-12 17:11:36

框架基础:ajax设计方案(二)---集成轮询技术的相关文章

轮询技术

1.轮询:浏览器不断地向服务器返送ajax请求.配合使用定时函数 setInterval 或者 settimeout 定时发送ajax请求. <script> setInterval(function(){ $.get('server.php',{id:5},function(data){ //根据服务器返回的数据进行下一步操作, }); },300); </script> 2.长轮询(comet):轮询是不断地发送ajax,而长轮询是浏览器发送一次ajax之后,服务器会去搜索数据

Ajax实现的长轮询不阻塞同一时间内页面的其他Ajax请求(同域请求)

最近要做一个来电的弹屏功能,利用OM 系统的接口,OM系统发送请求到接口程序,分析数据添加到mysql数据库中,然后把最新的数据id 跟今日来电的总的数量存储到memcache 中.弹屏程序根据读取的memcache 中的数据  比对,比较是不是有新的请求到来.中间遇到问题是:前台在轮询等待数据的时候,页面中的其他请求被阻塞,查了好多资料,包括 apache 的mpm 模式,都没有找到原因.后来 在论坛里边查到原因:如下 实际上是不能并发访问同一个站点使用了session的页面,因为访问A页面时

DNS轮询技术

1.DNS轮询:一个域名对应多个IP 原理图: 没加DNS轮询的基本架构 加了DNS轮询的架构图

apache日志轮询技术

1.首先先下载安装apache的日志轮询工具cronolog: 1 wget http://cronolog.org/download/cronolog-1.6.2.tar.gz 2 3 tar zxvf cronolog-1.6.2.tar.gz 4 5 cd cronolog-1.6.2 6 7 mkdir -p /usr/local/cronolog 8 9 ./configure --prefix=/usr/local/cronolog 10 11 make 12 13 make ins

前端框架之jQuery(二)----轮播图,放大镜

事件 页面载入   ready(fn)  //当DOM载入就绪可以查询及操纵时绑定一个要执行的函数.   $(document).ready(function(){}) -----------> $(function(){}) 事件处理   $("").on(eve,[selector],[data],fn)  // 在选择元素上绑定一个或多个事件的事件处理函数.    //  .on的selector参数是筛选出调用.on方法的dom元素的指定子元素,如:   //  $('u

php开发客服系统(持久连接+轮询+反向ajax)

欢迎在php严程序 - php教程学习AJAX教程, 本节课讲解:php开发客服系统(持久连接+轮询+反向ajax) php开发客服系统(下载源码) 用户端(可直接给客户发送消息)客服端(点击用户名.即可给该用户回复消息) 讲两种实现方式:一:iframe + 服务器推技术comet(反向ajax,即服务器向浏览器推送数据)二:ajax持久连接 + 长轮询 客服端采用第一种方式:iframe + 服务器推技术思路:1:新建comentbyiframe.php 该用文件使用while(true)一

ajax轮询与长轮询

  刚刚网了关于轮询的知识,必须拿到自己这里来做个备份了! 其实以前用ajax轮询做个及时数据更新的,只是当时做了不知道那个就是轮询. 首先我们什么时候会想到用轮询技术呢? 一般而言,最多的是及时信息更新,比如一个商城活动,参与人数的实时更新等,也还有人用来做过聊天室的,但是哈,轮询技术问题还是很多的,频繁的请求的服务器,服务器会把IP给你列入非白名单里,让你无法请求服务器.所以做及时的我还是建议用websocket 建立长连接. 其次小杨用一位老师的原话来讲解一下ajax轮询技术: 一.Aja

用大白话揭开Ajax长轮询(long polling)的神秘面纱

在看这篇Ajax长轮询之前可以先看看Ajax轮询技术(没有长),有助于理解: Ajax长轮询属于Ajax轮询的升级版,在客户端和服务端都进行了一些改造,使得消耗更低,速度更快. "不间断的通过Ajax查询服务端". 来,小二,先上代码~: Reception.html //客户端 <html> <head> <title></title> <script src="http://lib.sinaapp.com/js/jqu

实现web消息推送的技术和采用长轮询corundumstudio介绍

实时消息的推送,PC端的推送技术可以使用socket建立一个长连接来实现.传统的web服务都是客户端发出请求,服务端给出响应.但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推送消息到客户端. 有哪些可以实现web消息推送的技术: 不断地轮询(俗称“拉”,polling)是获取实时消息的一个手段:Ajax 隔一段时间(通常使用 JavaScript 的 setTimeout 函数)就去服务器查询是否有改变,从而进行增量式的更新.但是间隔多长时间去查询成了问题,因为性能和即