直接说结论:
长连接:TCP连接一直不断开的连接
keep-alive能实现长连接。
1.但是有时间限制,最多时间长一些而已 2.需要服务端也支持keep-alive,因为TCP连接的断开是双向的,不是客户端说我要保持连接就行
keep-alive实现的长连接和websocket的长连接不同:
keep-alive是HTTP协议层面的长连接,不能主动推消息,主要是进行连接复用的
websocket是websocket协议的长连接,只要不断开,连接一直都在,而且服务端可以主动推消息
keep-alive和websocket应用场景
- keep-alive用于需要发了HTTP请求后,需要连接复用的场景:
- 打开一个页面时,该页面链接了n个图片或n个js脚本或n个css等,并且这些东西都在一台server上;
- 需要用户频繁的在网站中转悠,这点点那点点;
- keep-alive不能用在短时间内高并发的场景
- websocket用于连接不多的场景或者需要服务端推送的场景,因为是长连接,所以服务器能提供的连接数是有限的。
HTTP长轮询:服务器收到请求后如果有数据, 立刻响应请求; 如果没有数据就会 hold 一段时间,这段时间内如果有数据立刻响应请求; 如果时间到了还没有数据, 则响应 http 请求;浏览器受到 http 响应后立在发送一个同样http 请求查询是否有数据;
(长轮询个人理解:“服务端hold住请求”如何实现?是不是有个死循环在一直监测,有数据变化就返回。)
HTTP短轮询:服务器收到请求不管是否有数据都直接响应 http 请求; 浏览器受到 http 响应隔一段时间在发送同样的http 请求查询是否有数据;
长轮询短轮询使用场景:
- 长轮询多用于web聊天场景,实时性高,还有一个web微信登录扫码的场景也是用的长轮询,手机一扫二维码,网页就显示用户头像
- 短轮询多用于实时性不高的场景。(celery查询状态就是短轮询,要注意结合keep-alive使用)
HTTP协议的核心: 先有请求,才有响应。有了请求,就要建TCP连接。所以造就了服务端没办法主动推消息,因为找不到发给谁。
在http早期,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。
使用keep-alive可以在一次TCP连接中可以持续发送多份数据而不会断开连接。
Httpd守护进程,提供了keep-alive timeout时间设置参数。
这个keepalive_timout意味着:一个http请求产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才关闭这个socket连接。
设置:Keep-Alive: timeout=5, max=100 // 第一次HTTP请求5秒后自动断开TCP连接,5s内HTTP请求超过100次,断开TCP连接。
keepalive由客户端发HTTP请求(建立TCP连接)时进行设置
HTTP的keep-alive 跟 TCP的keep-alive是两个不同的东西
HTTP的keep-alive说的是我这次请求的TCP连接要保持多长时间不关闭。
TCP的keep-alive是监测我TCP连接保持的这段时间内,双方是不是通的,不通就关闭TCP连接。
设置了keep-alive(http请求头)就是长连接(socket)了吗?
长连接是什么? 长连接是socket建立后一直不关闭,叫长连接。
短连接是什么?短连接是socket建立,通讯一次后,关闭socket。
所以,长连接和短连接在于client和server采取的socket关闭策略。服务器是资源提供者,所以服务器的连接关闭策略就很重要了
所以,问题变成:
设置了keep-alive(http请求头)服务端socket就不关闭了吗?
显然需要请求和服务器双方都设置keep-alive才行。 可以在不同的服务器软件中设定这个时间,nginx,或Apache的keep-alive时间
设置了keep-alive(http请求头),高并发场景服务端设置keep-alive合适吗?
如果同时有大量请求,服务端socket短时间得不到释放,肯定崩溃
双方都支持keep-alive了,用在哪些场景?
- 打开一个页面时,该页面链接了n个图片或n个js脚本或n个css等,并且这些东西都在一台server上;
- 需要用户频繁的在网站中转悠,这点点那点点;
keep-alive能实现长连接(有时间限制的长连接),但是这个连接除了拿来复用之外没别的用处。和websocket的长连接有什么区别呢
这是协议层面的区别。http 协议规定了 http 连接是一个一来(request)一回(response)的过程。一个请求获得一个响应后必须断掉。而且只有先有请求才会有响应。拿 http1.1 keep-alive 来说,即使底层 tcp 连接没有断,服务端无缘无故给浏览器发一个 http 响应,浏览器是不收的,他找不到收的人啊,因为这个响应没有对应的请求。你看 ajax 必须先发请求才会有一个 onsuccess 回调来响应这个请求。这个 onsuccess 的回调会在你 ajax 不发送的情况下被调用到吗?
而 WebSocket 协议不同,他通过握手之后规定说你连接给我保持着,别断咯。所以浏览器服务器在这种情况下可以相互的发送消息。浏览器端 new 一个 WebSocket 之后注册 onmessage 回调,那么这个 onmessage 可以被反复调用,只要服务器端有消息过来。而不会说是 new 一个 WebSocket onmessage 只会被调用一次,下次还得再 new 一个 websocket。
上面说到 http 连接,tcp 连接,websockt 连接到底啥区别。其实这是新人最容易搞不懂的地方。接下来我就要胡诌了,为啥说胡诌,因为我只是看了个皮毛,然后按我自己的理解说下区别。网络5层分层(自下而上):
物理层
数据链路层
网络层
传输层
应用层
http,websocket都是应用层协议,他们规定的是数据怎么封装,而他们传输的通道是下层提供的。就是说无论是 http 请求,还是 WebSocket 请求,他们用的连接都是传输层提供的,即 tcp 连接(传输层还有 udp 连接)。只是说 http1.0 协议规定,你一个请求获得一个响应后,你要把连接关掉。所以你用 http 协议发送的请求是无法做到一直连着的(如果服务器一直不返回也可以保持相当一段时间,但是也会有超时而被断掉)。而 WebSocket 协议规定说等握手完成后我们的连接不能断哈。虽然 WebSocket 握手用的是 http 请求,但是请求头和响应头里面都有特殊字段,当浏览器或者服务端收到后会做相应的协议转换。所以 http 请求被 hold 住不返回的长连接和 WebSocket 的连接是有本质区别的。