最近在一次采访中,我被问到如何处理在线聊天客户端应用程序.我经历了标准的"民意调查"解决方案,但因为面试官正在寻找"HTTP 1.1 keep-alive"方法而被切断了.使用HTTP已经有一段时间并且记住整点都是"无状态"的,这一点从来没有发生在我身上(更不用说保持活着并没有一贯地实现).
我的问题是,当设置"keep-alive"标头时,Web服务器是否可以向客户端广播和/或发送信息?
使用HTTP 1.1,keep-alive是默认行为.(在HTTP 1.0中,默认行为是关闭连接.)服务器必须发送'Connection:close'标头以终止与第一个响应的连接.因此仍然有一个TCP套接字可用于推送数据,但只是从服务器推送数据会以一种主要方式违反HTTP协议.即使使用keep-alive,客户端仍然需要轮询服务器.
区分HTTP Keepalive和TCP Keepalive很重要.HTTP keepalive可防止服务器或客户端关闭连接.当连接可能长时间处于空闲状态并且可能被NAT代理或防火墙丢弃时,将使用TCP keepalive.通过setsockopt()调用在每个套接字的基础上激活TCP keepalive.
在进行"长轮询"以消除重新轮询的需要时,可能需要TCP keepalive.
Keep-alive只是保持TCP套接字打开,所以每次轮询时,都会节省TCP setup/teardown数据包的开销 - 但是你仍然需要轮询.
但是,"长轮询"是Web服务器向客户端广播通知的策略.本质上,客户端发出GET请求,但Web服务器不会立即响应,而是等待它们发送通知,此时它们会响应GET请求.这消除了为了轮询而不需要数据包穿过线路,并保持连接无状态,正如您正确提到的那样是协议的目的之一.
您可以阅读有关Comet服务器的更多信息.这听起来基本上就像采访者所询问的那样.它们的有效性受到一些人的质疑,但它已被用于几种类似的情况.
例如,我相信gmail使用彗星技术来做某些事情(但不要引用我的内容).
另一个似乎相关的例子是BOSH,它是一种使用HTTP和XMPP传输聊天信息的协议.但我不相信使用keep-alive会涉及到这一点.