这种技术又叫反向Ajax,能够模拟服务器端想客户端的推送,只是在请求到达时服务器不马上进行响应,待有用数据处理完成后再进行response,简单测试了一下,没有进行超时设置(服务端,发送端均没设置,实际情况请自行斟酌)。至少服务器断睡1分钟是没有问题的
先上前端代码:
<!DOCTYPE html>
<html>
<head>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script type="text/javascript">
$(function() {
function connect(){
var xhr = new XMLHttpRequest();
xhr.open("POST", "do.jsp?num="+$("#Num").html(), true);
function DoResult(){
if(xhr.readyState == 4){
$("#Num").html(xhr.responseText);
connect();
}
}
xhr.onreadystatechange = DoResult;
xhr.send(null);
}
connect();
})
</script>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div id="Num">
7
</div>
</body>
</html>
js内对connection方法进行貌似递归的调用,每次把当前页面div中的值传入后台do.jsp进行处理,成功返回后修改div中的值,再次携带当前div中的值发送ajax请求,为什么要携带当前值?因为后台如果判断前断值和后端值不一致时可以直接返回刷新页面而迅速同步前后端的值。没有对timeout或是failure的情况进行定义,可以自行斟酌添加。
下面是do.jsp:
<%@page import="com.ajax.Keeper"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%
String num = request.getParameter("num");
if(num==null)
num = "0";
out.print(Keeper.getPrice(num));
%>
很简单,直接上keeper类:keeper类模拟服务器端对一个静态值进行修改:start()方法,在修改后通知客户端进行同步 getPrice()方法。
package com.ajax;
public class Keeper {
private static int price = 100;
private static final Object lock = new Object();
static{
new Thread(new Runnable() {
@Override
public void run() {
try {
start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static int getPrice(String last) throws InterruptedException{
System.out.println(last);
if(!last.equals(Integer.toString(price)))
return price;
synchronized(lock){
lock.wait();
}
return price;
}
public static void start() throws InterruptedException{
while(true){
Thread.sleep(60000);
price--;
synchronized(lock){
lock.notifyAll();
}
}
}
}