Ajax的出现使Comet成为可能。 HTTP的单方面性质可以有效避免。 实际上,有几种方法可以绕过这个。 您可能已经知道,支持Comet的最简单方法是轮询。 使用XMLHttpRequest对服务器进行调用,返回,等待一段时间(通常使用JavaScript settimeout函数),然后重新调用。 这是非常普通的技术。 例如,大多数webmail APP应用程序都使用此技术在电子邮件到达时显示电子邮件。
这个技术有优点也有缺点。 在这种情况下,我们希望像其他Ajax请求一样迅速回复。 请求之间需要暂停。 否则,连续的请求会破坏服务,在这种情况下,显然没有可伸缩性。 此暂停会导致APP应用程序延迟。 的暂停时间越长,服务器上的新数据到达客户端所需的时间就越长。 缩短暂停时间会面临服务器崩溃的风险。 但另一方面,这显然是最简单的实现Comet的方式。
现在,很多人应该认为轮询不属于Comet。 相反,他们认为Comet是对轮询极限的一种解决方案。 最常见的“真的”Comet技术是轮询的变体,并且是长轮询。 轮询和长轮询的主要区别在于服务器需要多长时间才能做出响应。 轮询通常会长时间保持连接。 通常是几秒钟,但也可能超过一分钟。 当服务器上发生事件时,将发送响应,立即关闭,并且轮询将立即重新开始。
长轮询相对于典型轮询的优点是,一旦数据可用,它就会立即从服务器发送到客户端。 请求可能会等待很长时间,在此期间不会返回任何内容,但只要有新数据,就会立即发送到客户端。 所以没有延迟。 如果您使用过基于Web的聊天程序或声称“实时”的程序,则很可能正在使用此技术。
长轮询有很多种。 这是第三种样式的Comet。 这通常被称为流。 在此样式中,服务将数据发送回客户端,但不关闭连接。 连接在过期之前保持打开状态,然后重新提交请求。 XMLHttpRequest规范检查readyState的值是否为3或Receiving,而不是4或Loaded,表明可以从服务器检索“溢出”的数据。 和长轮询一样,这种方式也没有延迟。 服务器上的数据准备好后,该数据将发送到客户端。 此方法的另一个优点是可以大大减少对服务的请求,从而避免与设置服务连接相关的开销和延迟。 不幸的是,XMLHttpRequest在不同的浏览器中有很多不同的实现。 该技术只能确保在更新版本的Mozilla Firefox中使用。 对于Internet Explorer或Safari,需要长时间的轮询。
这样,你可能会认为长轮询和流量有很大的问题。 请求需要很长时间在服务器上。 这打破了每个请求使用一个线程的模式,因为用于一个请求的线程没有被释放。 更糟糕的是,除非发送回数据,否则线程将保持空闲。 这显然没有可伸缩性。 幸运的是,现代的Java Web服务器有很多解决这个问题的方法。