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 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 */
	}
}

客户端,





测试keep-live




	

可以看到,即使Ajax显示这是Connection为close
 req.setRequestHeader("Connection", "close");
但是,被jquery拒绝了

Http长链接和Connection:keep-alive的解答_第1张图片

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

你可能感兴趣的:(网络编程,websocket,ajax,浏览器,服务器,通信)