Ajax实现Web长连接

来源:互联网 发布:mac如何解压文件 编辑:程序博客网 时间:2024/05/01 01:47

这篇文章写的很好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, HttpServletResponse response) throws ServletException, 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();    }}
1 0