基于Iframe的流方式
原理
基于Iframe的流方式的原理主要是,在页面隐藏一个iframe,前台设定定时器修改iframe的src属性设为对一个长连接的请求,服务器返回对页面函数的调用,函数的参数为服务器处理的数据。
Iframe的流方式的过程如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YF5313Dm-1651461949488)(http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig003.jpg#pic_center)]
上节提到的 AJAX 方案是在 JavaScript 里处理 XMLHttpRequest 从服务器取回的数据,然后 Javascript 可以很方便的去控制 HTML 页面的显示。同样的思路用在 iframe 方案的客户端,iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如“”。服务器端将返回的数据作为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。
实例:
后台主要是获取需要显示的数据,传给返回前台调用的函数即可,下面是iframe流方式后台代码
/**
* iframe 实现服务器推
* @author 马艺俊
*
*/
public class IframeCometServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
PrintWriter pw = resp.getWriter();
MessageDao msgDao = new MessageDao();
int num = msgDao.getMsgNum();
//返回对前台函数的调用,并将数据传入函数
pw.println("<script>parent.changeNumber("+num+")</script>");
pw.flush();
}
}
前台主要是隐藏一个iframe,定时刷新iframe,响应的时候调用后台写入的在页面定义好的函数刷新信息
<%@ 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(){
setInterval(function(){
//定时刷新iframe
$("#polling").attr("src","IframeCometServlet");
},5000);
});
//定义一个js函数,由服务断写到iframe里的js调用,但是这时,chrome标签上的圆圈一直在转
function changeNumber(num) {
document.getElementById("number").innerHTML = num;
}
</script>
</head>
<body>
<h1>test comet</h1> <br>
您有<span id="number">0</span>条消息!
<iframe id="polling" name="polling" src="IframeCometServlet" style="display:none;"></if rame>
</body>
</html>
测试
部署应用,访问http://localhost:8088/IframeCometDemo/iframeCometPage.jsp
可以看到数据返回来了,同样写入数据后,页面的信息也会实时更新
但是有一点不好的就是iframe流方式每次发送请求的时候,chrome地址栏上的加载图标都会转圈,但是ie正常,暂时还没找到解决方案。