分享

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

 WindySky 2017-12-25

Jquery Ajax长轮询

原理

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

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

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

输入图片说明

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

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

  2. 请求超时,断开连接

实例

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

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

/**
 * 基于http长连接的ajax长轮询实现消息提醒
 * @author 马艺俊
 *
 */
public class JsLongPollingMsgServlet extends HttpServlet {

@Override
protected 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

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多