Http长链接和Connection:keep-alive的解答

来源:互联网 发布:mac可以下载爱思助手 编辑:程序博客网 时间:2024/05/15 14:39

因为自己使用http请求都是,请求-应答这种方式,一直以为http是短链接的。每次通信后,其链接断开。

其实不然,http1.1开始。客户端的请求头带上

  1. Connection:
    keep-alive
便是维持长链接。当然这个需要服务器的支持。

该方式可以使一次TCP连接为同意用户的多次请求服务,提高了响应速度。
因为http是无状态的,而且keep-live只是个建议
因此,如果要实现服务器和浏览器的长链接全双工通信,还是用websocket吧

下面是Connection:keep live的测试过程,验证了浏览器甚至Ajax都是用了这个默认下的消息头,即长链接。

服务端

@Controllerpublic class AjaxController implements CommandLineRunner {public static final AtomicInteger count = new AtomicInteger();public static final ConcurrentHashMap<String, HttpServletResponse> session_map = new ConcurrentHashMap<>();@RequestMapping("/b")public void b(HttpServletRequest req, HttpServletResponse resp, Model model) throws Exception {allowAccess(resp);LogCore.BASE.info("start"+session_map.size());String sid = req.getRequestedSessionId();if(null !=sid){session_map.put(req.getRequestedSessionId(), resp);}}@Overridepublic void run(String... args) throws Exception {LogCore.BASE.info("{} init start!!!! ", this.getClass().getName());Timer t = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {//LogCore.BASE.info("." + session_map.size());session_map.values().forEach(x -> {try {x.getWriter().write("\ntimer" + count.incrementAndGet());} catch (Exception e) {e.printStackTrace();t.cancel();LogCore.BASE.info("end");}});}};t.schedule(task, 0, 1000);}private void allowAccess(HttpServletResponse resp) {/* 跨域 begin */resp.setHeader("Access-Control-Allow-Headers", "Content-Type");resp.setHeader("Access-Control-Allow-Origin", "*");resp.setHeader("Access-Control-Allow-Methods", "GET");resp.setHeader("Allow", "GET");/* 跨域 end */}}

客户端,

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>测试keep-live</title><script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script></head><script type="text/javascript">function click1(){       $.ajax({        type: "POST",        url: "http://localhost:8080/b",        data: {            sign: "testsign"        },        beforeSend: function(req) {            req.setRequestHeader("Connection", "close");        },        success: function(data) {         console.log(data)        $('.detial_f').show().html(data);        },        error: function() {            alert("fail!!!,请刷新再试!");        }    });}</script><body><div class="button_control"><button onclick ="click1()" class="button_start">按钮</button></div><div class="test"><p class="detial_f"></p></div></body></html>
可以看到,即使Ajax显示这是Connection为close
 req.setRequestHeader("Connection", "close");
但是,被jquery拒绝了


因此以后就不用考虑Connection:keep-live的问题了,不管怎样,http维持一段长连接,可以减少下一层TCP/IP三次握手四次挥手的建立,多个请求复用一个连接,提高了性能。

0 0