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

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

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

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

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

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

服务端

@Controller
public 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);
		}
	}

	@Override
	public void run(String... args) throws Exception {
		LogCore.BASE.info("{} init start!!!! ", this.getClass().getName());
		Timer t = new Timer();
		TimerTask task = new TimerTask() {
			@Override
			public 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三次握手四次挥手的建立,多个请求复用一个连接,提高了性能。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值