这篇文章写的很好Web 通信 之 长连接、长轮询(long polling),受益匪浅。
1.什么是长轮询,长连接
用通俗易懂的话来说,就是客户端不停的向服务器发送请求以获取最新的数据信息。这里的“不停”其实是有停止的,只是我们人眼无法分辨是否停止,它只是一种快速的停下然后又立即开始连接而已。
2.我的应用场景
想做一个二维码签到系统.
主要要求:
- 在浏览器上发布签到
- 一个二维码只能用一次
- 当浏览器上显示的二维码被使用过后,自动刷新成新的二维码
3.具体代码
页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title></title>
</head>
<script type="text/javascript">
function myajax() {
var myhttp;
myhttp=new XMLHttpRequest();
myhttp.open("GET","qrajax",true);
myhttp.send();
myhttp.onreadystatechange=function()
{
if (myhttp.readyState==4 && myhttp.status==200)
{
var msg=myhttp.responseText;
document.getElementById("asd").innerHTML=msg;
if(msg!="Failed"){
document.getElementById("QRcode").src=
"qrcoder?flag="+Math.random()+"&teacherID="+document.getElementById("tecID").value;
}
}
}
}
//长轮询,10秒发送一次ajax请求
window.setInterval(myajax,10000);
</script>
<body>
<textarea id="asd"></textarea>
<img src="qr" id="qrajax"/>
<input type="text" id="tecID"/>
<button type="button" onclick="myajax()">Change Content</button>
</body>
</html>
服务器端
package com.servlet;
import com.service.QRService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
public class QRAjax extends HttpServlet {
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request,IOException {
HttpSession session=request.getSession();
QRService service=new QRService();
PrintWriter out = response.getWriter();
//计时
int time=0;
if(session!=null){
//长轮询
while(true) {
time++;
//判断二维码是否被使用过
if (service.isReflash()) {
out.print("no "+session.getAttribute("recordCount")+" ");
break;
}else{
//保持10秒
if(time>=10){
out.print("Failed");
break;
}else {
try {
//保持住,1秒循环一次
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
out.close();
}
}