Java+Spring长连接实现后台主动发送数据给前端

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JacXuan/article/details/79009795

1.什么是长连接、短连接?

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

前台代码:

<script type="text/javascript">
function ajaxLongConn(){
        $.ajax({
                type : "POST",
                //async : true, //同步执行
                timeout :180000,//单次超时长连接时间为三分钟
                url : "${ctx}/pollModel/timerPollReport.html",
                dataType : "JSON", //返回数据形式为json
                success : function(result) {
                    //请求成功不递归,整个web生命周期仅会成功一次
                    console.log(result);
                    var data = result.poll_report;
                    //setTimeout('alert("12465")',5000);
                    popMsg(data.pollTime,data.pollId,data.totalPoll, data.errPresent, data.errTotal);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (textStatus == "timeout") { // 请求超时
                        ajaxLongConn(); // 递归调用
                        // 其他错误,如网络错误等
                    } else {
                        ajaxLongConn();
                    }
                },
            });
        }
        ajaxLongConn();
  </sricpt>

其实长连接在前端做了这几件事:
1.为了避免反复提交请求询问信息,将连接持续时间增加。
2.如果失败立即重新提交轮询请求。
这样就保证后台时时刻刻和前端时时刻刻保持连接,一旦后台返回数据,前端可以第一时间接收到。

后端代码:

@RequestMapping(value = "/timerPollReport", produces = "text/html;charset=UTF-8;")
    public @ResponseBody String timerPollReport(){
        Map<String,Object> report;
        Date nowDate;
        //hold住连接
        while(true){
            try {
                nowDate = new Date();
                if(!StringUtils.isNull(PollCron.sendReport) && nowDate.compareTo(PollCron.sendReport) >= 0){//决定返回条件,可自定义。如数据库发生变化返回等
                    report = PollCron.reportMap;
                    System.out.println("report:"+report);
                    return JsonUtil.objToJson(report);
                }
                Thread.sleep(30000);//防止循序太频繁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

长连接或者长轮询名义上实现了后台主动推送数据的功能,其实还是前端发送请求,后台择时返回。

展开阅读全文

没有更多推荐了,返回首页