Ajax长连接

来源:互联网 发布:企业人员优化方案 编辑:程序博客网 时间:2024/04/30 17:16

这种技术又叫反向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() {@Overridepublic 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();}}}}


当请求到达执行getPrice方法,多个请求对lock对象竞争,得到的进入代码块,然后wait()放弃锁。而减价线程对price进行修改,1M一次,并竞争lock对象释放lock对象waittingroom中的线程。由于notify与外部请求会同时竞争Lock对象,所以计时未必特别准确,但这个缺陷不影响服务器端和客户端的内容一直性,然后在多个线程在返回当前price时会对lock对象进行竞争,做不到完全的同时返回。究竟差多少能不能满足需求。还需要进一步的考量,还有一种做法是服务端getPrice方法内部进行循环并设置标志位,但效率恐怕是不会高,而且标志位如何控制,其实也十分困难。




0 0
原创粉丝点击