您的位置:首页 > 其它

关于push技术(long polling)和长连接keepalive的一些疑问

2015-05-09 16:14 429 查看
http://www.zhihu.com/question/25504043


关于push技术和长连接的一些疑问?

现在大多数push技术,比long polling,看了些资料就是,服务器挂起请求的连接。到有事件,或者超时的时候,再返回。然后再重新建立连接。请问为什么不直接利用keepalive 一直保持连接。这样不也可以实时通信么

3
条评论 分享

按投票排序按时间排序


7 个回答

赞同26
反对,不会显示你的姓名




大房,我家有女初长成!

cellier、知乎用户、知乎用户 等人赞同

现在大多数push技术,比long polling,看了些资料就是,服务器挂起请求的连接。到有事件,或者超时的时候,再返回。然后再重新建立连接。请问为什么不直接利用keepalive 一直保持连接。这样不也可以实时通信么
首先回答你的问题,是的,如果有了keepalive,那么你所描述“重新建立连接”在超时时间内是不需要的。但是不管是否有keepalive,long polling实现的就是实时通信。

更进一步,你需要理解几个概念,帮助你更好的理解所谓的实时通信。

第一,从Socket层面来讲,客户端(浏览器)通过三步握手和服务端建立连接,然后就可以通过这条socket通道传输(双向)数据;所以,如果浏览器可以支持socket通信,那么实时通信就简单很多,不需要“有了事件返回,然后客户端再发起请求”,注意我这里的描述,不是“到有事件,或者超时的时候,再返回。然后再重新建立连接” 而是发起“请求”。现在的websocket让socket成为可能。

socket是全双工,也就是,一旦这个连接通过三次握手建立好之后,不管是客户端还是服务端,在任何时候都可以主动的读或者写数据;所以这就要求你的socket客户端和服务器端,能同时处理读和写的请求。

第二,理解HTTP协议很重要我高亮了协议,既然它是个协议,那建立连接,发送数据,和接收数据,都和它没关系(这里不完全正确,但是帮助理解。HTTP协议定义的一些参数,会指导数据连接的建立和传输,但是只是指导!),它仅仅是个协议!协议!,什么意思,就是你定义的一个数据结构,定义了数据传输链路上传输的数据格式而已,只不过,这个数据结构是RFC公认的。

HTTP请求协议的例子:


GET /?a=b&c=d HTTP/1.1\r\n

Host: http://www.a.com\r\n

Connection: keep-alive\r\n

Accept-Language: en,zh-CN;q=0.8,zh;q=0.6\r\n

\r\n

a=b&c=d

HTTP响应协议的例子:

HTTP/1.1 200 OK\r\n

Date: Wed, 24 Sep 2014 01:07:23 GMT\r\n

Content-Type: text/html\r\n

Connection: Keep-Alive\r\n

Content-Length: 10\r\n

\r\n

{ack:0}

第三,所谓的HTTP服务器,其实是能同时处理socket数据传输,以及HTTP协议解析的一个工具;它能处理来自客户端的socket请求,建立socket连接和处理这条连接上传输的数据,这个数据,是符合HTTP协议规范的,对任何不符合规范的数据,统统报错或者丢弃。另外,还有一点很重要,HTTP服务器在接收到符合HTTP协议的数据后,只会通过某种方式(cgi, fcgi, wsgi等)把数据投递给你(一般你拿到的是你的开发框架包装过的request或者response,可以直接操作http
header和http data),但是,并不会把这个socket连接expose给你,理解这点也很重要。

第四, 大家熟悉的 Brower 浏览器,也就是long polling的载体,它的一部分功能,就是一个socket client,同时这个socket client仅处理符合HTTP协议的数据传输。

那么,再回到你的问题。常规情况下,如果没有keepalive,那么,浏览器再发送了一个HTTP请求以后并成功获得了服务端的HTTP响应(参见上面的协议),就会把这个socket通道通过四次握手关闭;所以,一个http请求+一个http响应后,服务端就不能再继续往浏览器这个客户端发送数据。那么,有了keepalive,会造成什么?当浏览器和服务端都发现支持keepalive的话,一次Http的request和reponse后,浏览器和服务器都不会关闭这条socket通道,如果有基于这条socket通道的后续HTTP数据传输(注意这个数据传输一定是先request后response),可以重用这条链路。那么,既然这条socket没有关闭,为什么不能再次推送数据下去?前面提到了,HTTP没有expose这条socket给你,你只有数据,怎么push?即使可以再次push,这条socket链路已经发送了一次http
header和http data了,浏览器那边如果再次收到数据,也是不符合HTTP协议的!当然基于chunked可以做一些优化。

概念很多,讲清楚也比较困难,有问题再私信吧!!

编辑于 2014-09-24 6
条评论

赞同17
反对,不会显示你的姓名




刘缙,系统编程

lshxjtu、知乎用户、稗田阿求 等人赞同

因为HTTP本身是不对称的,虽然你用Connection: Keep-Alive保持了TCP连接,在client没有发request的时候,server还是不能发response

所以long polling要求client在收到response之后马上再发一个request,把client主动的不对称信道转换为server主动的不对称信道。

编辑于 2014-09-23 2
条评论

赞同0
反对,不会显示你的姓名




知乎用户,被超过50种协议折腾过然后幸存下来

1)KeepAlive 确实可以保持长连接的活跃,但是长连接活跃不意味着就是“实时通信”。

你问题里面的“实时通信”其实我不太明白是什么意思,是指IM呢,还是指延迟很低呢?

前者的话IM一般都走UDP啊,这样更快,后面讲。

后者的话现代服务器建立连接的延迟其实并不高,高的是认证,授权,计费等阶段的逻辑处理。

2)在网络里面,如果为了最求吞吐量和速度,必须尽量让协议保证无状态。

状态会需要context来维持。

状态加入协议设计的复杂度,例如N次shake。

状态会让服务器消耗等待,并且短时间内无法释放。

状态并行性很差。

无状态的协议没有上面的缺点。

3)push技术就是为了降低服务器维护client的复杂度。

long polling没学过,不太懂这是啥,如果是指polling的interval很长,那么最终目的也是为了减少频繁polling引入的overhead,现在的基础网络都很好,而且应用的链接都会维持较久,没有必要像poll中断那样poll应用层。

发布于 2014-09-24 4
条评论

赞同2
反对,不会显示你的姓名


匿名用户

知乎用户、Locke
Huang 赞同

KeepAlive是相对于TCP来说的,就是多个HTTP请求使用同一条TCP通道,省掉三步握手。而long polling是对于HTTP来说的。浏览器发起一个HTTP请求后,服务器不返回,而是一直挂着,当有消息的时候返回。浏览器这里一直等着这个请求,一返回马上可以处理数据。超时只是一个补充手段,因为不可能让这个HTTP请求一直挂着,比如浏览器关掉呢?那这个请求就会消耗服务器资源。所以设个超时。一般long polling的实现技术就是ajax,异步等待HTTP应答。在success
handler中处理消息。只要服务器返回数据,就会马上调用handler,这样实时性比较高

编辑于 2014-09-23 1
条评论

赞同0
反对,不会显示你的姓名




pig
pig,网管

说白了,那就是做web的想实现socket,但以前的主流协议与浏览器对socket不支持或支持的不好,没办法了,才用改进版的轮询做了个所谓的push。

发布于 2014-09-25 添加评论

赞同0
反对,不会显示你的姓名




知who,知呼?

websocket 啊,不用 Long Polling 这么啰嗦!

发布于 2014-09-25 1
条评论

赞同0
反对,不会显示你的姓名




知乎用户,http://chengshuguang.com

http协议自身的问题,虽然建立在tcp之上,但是不是全双工通讯,,通讯的发起者只能是浏览器,不能server端主动推送给浏览器(浏览器问,服务器答,一问一答一问一答怎样下去。。。),,所以现在出现了很多技术来解决这个问题(comet, SPDY, websocet, 后两个从协议方面解决弥补)。keepalive只是为了重用连接,不用每次请求都重新建立,但是不能改变一问一答的模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: