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

Jquery Ajax长轮询

原理

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FuQ6AEkk-1651461291361)(http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig002.jpg#pic_center)]

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

  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看下客户端发送请求的特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cREPgjmx-1651198657134)(https://static.oschina.net/uploads/img/201611/24163407_Jqfv.png "在这里输入图片标题")]

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

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

在这里插入图片描述

再看看longPollingPage.jsp

在这里插入图片描述

消息回来了~

再看看请求的样子

在这里插入图片描述

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

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值