WEB消息提醒实现之二 实现方式-Jquery Ajax长轮询

来源:互联网 发布:查询域名的二级域名 编辑:程序博客网 时间:2024/06/05 15:07

Jquery Ajax长轮询

原理

Jquery Ajax长轮询的原理主要是,前台客户端发送ajax请求到服务器,服务器接收到请求之后会保持住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器保持住连接会消耗资源。

jquery ajax长轮询的过程如下图:

输入图片说明

可以看到,长轮询的关闭连接有两种情况:

  1. 服务器有新的数据,正常响应,断开连接

  2. 请求超时,断开连接

实例

发送消息的Servlet和前面的一样

下面是长轮询时候服务器的Servlet:

/** * 基于http长连接的ajax长轮询实现消息提醒 * @author 马艺俊 * */public class JsLongPollingMsgServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException {    req.setCharacterEncoding("utf-8");    PrintWriter out = resp.getWriter();    MessageDao msgDao = new MessageDao();    String pageMsgNumStr = req.getParameter("pageMsgNum");    if(pageMsgNumStr==null || "".equals(pageMsgNumStr)){        pageMsgNumStr = "0";    }    int pageMsgNum = Integer.parseInt(pageMsgNumStr);    int num = 0;    StringBuffer json = null;    while(true){        num = msgDao.getMsgNum();        //数据发生改变 将数据响应客户端        if(num != pageMsgNum){            json = new StringBuffer("{");            json.append("\"msgNum\":"+num);            json.append("}");            break;        }else{            //没有新的数据 保持住连接            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    out.write(json.toString());    out.close();}}

在这个Servlet里,接受到请求之后会进入一个死循环,循环里面会判断消息数据是否发生了改变,如果没改变的话会保持住连接,要是这段时间到了连接超时时间,请求会超时,服务器断开连接,客户端则会重新建立请求;要是这段时间检测到有数据改变,则会将数据响应给客户端,正常断开连接,客户端再重新建立请求。

下面是长轮询的页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServ    erPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head><base href="<%=basePath%>"><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--><script type="text/javascript" src="jquery-easyui-v1.4.4/jquery.min.js"></script><script type="text/javascript">$(function(){    getMsgNum();});function getMsgNum(){    $.ajax({        url:'JsLongPollingMsgServlet',        type:'post',        dataType:'json',        data:{"pageMsgNum":$("#pageMsgNum").val()},        timeout:5000,        success:function(data, textStatus){            if(data && data.msgNum){                                    //请求成功,刷新数据                $("#msgNum").html(data.msgNum);                                    //这个是用来和后台数据作对比判断是否发生了改变                $("#pageMsgNum").val(data.msgNum);            }             if(textStatus == "success"){                                    //成功之后,再发送请求,递归调用                getMsgNum();            }        },        error:function(XMLHttpRequest, textStatus, errorThrown){            if(textStatus == "timeout"){                                    //有效时间内没有响应,请求超时,重新发请求                getMsgNum();            }else{                                    // 其他的错误,如网络错误等                getMsgNum();            }        }    });}</script>  </head>  <body><div>    <input id="pageMsgNum" name="pageMsgNum" type="hidden"/>    您有<span id="msgNum" style="color: red;">0</span>条消息!</div><div>    <p id="title">title</p>    <p id="content">content</p></div>  </body></html>

测试

应用部署完后,访问轮询页面http://localhost:8088/JsLongPollingDemo/longPollingPage.jsp

输入图片说明

现在还没有新的消息,我们可以按F12看下客户端发送请求的特点

输入图片说明

可以看到,客户端每次发送请求之后,5s(请求超时时间)内由于后台服务器保持住连接并且没有响应前台,所以5s后请求超时了,请求被取消(cancel),然后客户端又重新发送了请求

我们访问发送消息的页面,提交新消息

输入图片说明

再看看longPollingPage.jsp

输入图片说明

消息回来了~

再看看请求的样子

输入图片说明

可以看到,我们提交了消息之后,轮询请求检测到数据发生变化,就正常地返回数据响应了

0 1
原创粉丝点击