http://www.zhihu.com/question/25504043
关于push技术和长连接的一些疑问?
现在大多数push技术,比long polling,看了些资料就是,服务器挂起请求的连接。到有事件,或者超时的时候,再返回。然后再重新建立连接。请问为什么不直接利用keepalive 一直保持连接。这样不也可以实时通信么
按投票排序
按时间排序
7 个回答
现在大多数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可以做一些优化。
概念很多,讲清楚也比较困难,有问题再私信吧!!