Comet Jetty/Tomcat,Firefox 和 Chrome 存在一些浏览器问题
我正在探索如何在我正在进行的项目中使用 Comet。
我尝试首先使用 Tomcat6 和 CometProcessor API 创建测试应用程序,然后使用 Jetty7 Continuations 创建测试应用程序。
该应用程序在两者上都可以工作,但我在消息的实际显示方面遇到了一些问题。
我使用了创建 XMLHttpRequest 连接并始终保持打开状态的技术,以便服务器可以在可用时将数据持续推送到所有连接的客户端。
我的客户端代码与此类似:
function fn(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState==3){
document.getElementById('dv').innerHTML =(xhr.responseText);
}
if (xhr.readyState==4){
alert ('done');
}
}
xhr.open("GET", "First", true);
xhr.send(null);
}
我在网上某处发现了使用 readyState 3 的东西。
我目前面临两个问题:
在 Firefox 中,这段代码可以完美运行。但是如果我打开一个新选项卡甚至一个新的浏览器窗口,它不会与服务器建立新连接并且新选项卡或窗口上不会显示任何内容,只有第一个选项卡/窗口会获取展示。我使用 wireshark 来检查这一点,即使在打开第二个选项卡后,它也仅显示 1 个连接。我无法理解为什么会发生这种情况。我已经阅读过有关 2 个连接限制的内容,但这里只有一个连接。
其次在Chrome中,上面的代码不起作用,并且只有当我得到的服务器关闭连接时,回调才会在readystate为3时调用
我还想问用 Java 做 Comet 的最佳方法/框架是什么。我目前在客户端使用 jQuery。
任何建议将不胜感激!谢谢
I am exploring the use of Comet for a project I am working on.
I tried creating a test application first using Tomcat6 and CometProcessor API and then with Jetty7 Continuations.
The application is kind of working on both but I am having some issues with the actual display of messages.
I used the technique of creating an XMLHttpRequest Connection and keeping it open all the time so the server can continuously push data to all the clients connected whenever it is available.
My client side code is something similar to this:
function fn(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState==3){
document.getElementById('dv').innerHTML =(xhr.responseText);
}
if (xhr.readyState==4){
alert ('done');
}
}
xhr.open("GET", "First", true);
xhr.send(null);
}
I found this thing of using readyState 3 somewhere online.
I am facing 2 problems currently:
In Firefox this code works perfectly. But if I open a new tab or even a new browser window, it does not make a new connection to the server and nothing shows up on the new tab or window, only the first tab/window gets the display. I used wireshark to check this and its shows only 1 connection even after the 2nd tab is opened. I am unable to understand why this would happen. I have read about the 2 connection limit, but here there is only one connection.
Secondly in Chrome, the above code does not work, and the callback is not invoked for readystate of 3, only when the connection is closed by the server i get the output.
I would also like to ask which is the best way/framework for doing Comet with Java. I am currently using jQuery on the client side.
Any suggestions would be greatly appreciated!! Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Chrome 的这种有线行为确实很烦人。我试图找出GMail(Google自己的应用程序)如何在Chrome中实现Comet,但是没有合适的Http Sniffer来捕获Chrome的永久HTTP流量。
解决方案1:我最初的想法:
我们可以在 Comet Http 响应中包含“Content-Type: multipart/x-mixed-replace”标头。我测试过。如果响应是多部分的,则当 (xhr.readyState == 3) 为 true 时,xhr.responseText 不为空。
唯一的问题是 xhr.responseText 是整个响应,而不是像 Firefox 那样的“替换”响应。例如,服务器发送“A”,然后发送“B”来替换“A”,然后发送“C”来替换“B”。在 Firefox 中,当 xhr.readyState==4 时,您将得到“A”、“B”、“C”。在 Chrome 中,当 xhr.readyState == 3 时,您将得到“A”、“AB”和“ABC”。
因此,您的客户端 JavaScript 应该解析 xhr.responseText提取推送的数据。
解决方案2:
这是 Safari 推荐的 http://lists.macosforge.org /pipermail/webkit-dev/2007-June/002041.html.
Web 引擎不会呈现推送的数据,直到有足够的字节可以显示。据称需要初始 256 字节填充。我在 Chrome (4.1.249.1036 (41514)) 中尝试过。看起来需要大约 1 KB 才能触发第一个推送的负载(readyState == 3)。
确保 XHR 不是直接在 onload 事件处理程序中发送的。否则,页面的标题或 URL 栏中会有加载指示符。
This wired behavior of Chrome is really annoying. I tried to find out how GMail(Google's own application) implements Comet in Chrome, but there is no appropriate Http Sniffer to catch forever HTTP traffic of Chrome.
Solution 1: My original thought:
We can have "Content-Type: multipart/x-mixed-replace" header in Comet Http response. I tested it. If the response is multiparted, xhr.responseText is not empty when (xhr.readyState == 3) is true.
The only problem is that xhr.responseText is the whole response instead of "replaced" response as Firefox does. For example, the server send "A", then "B" to replace "A", then "C" to replace "B". In Firefox, you will get "A", "B", "C" when xhr.readyState==4. In Chrome, you will get "A", "AB" and "ABC" when xhr.readyState == 3.
So, you client javascript should to parse xhr.responseText to extract pushed data.
Solution 2:
This is recommend by Safari http://lists.macosforge.org/pipermail/webkit-dev/2007-June/002041.html.
Webit engine doesn't render pushed data until there are enough bytes to show. It is claimed to need initial 256 bytes padding. I tried in Chrome (4.1.249.1036 (41514)). It looks that about 1 kilo bytes is needed to have the first pushed payload trigger (readyState == 3).
Make sure the XHR is not sent directly sent in onload event handler. Otherwise, there is loading indicator in title or URL bar for the page.
将 comet 与 Jetty 一起使用可以很好地与 bayeux 和 dojo 配合使用。支持比简单的 XMLHttpRequest 更高级别。相反,您可以订阅单独的通道,并且能够注册在通道上出现特定事件时触发的函数。在单个浏览器中与不同选项卡建立多个连接非常简单,并且(根据我的经验)适用于 Firefox、Chrome 和 Safari。
我有一个用 Java 运行的服务器和用 JavaScript 运行的客户端。
Using comet with Jetty works well with bayeux and dojo. the support is higher level than simple XMLHttpRequest. Instead, you get subscriptions to separate channels, and the ability to register functions to be triggered when particular events appear on the channel. It's pretty straightforward to have multiple connections to different tabs in a single browser, and works (in my experience) with Firefox, Chrome, and Safari.
I have a server running in Java and clients in javascript.
我也对 Chrome 的行为不满意。
我的解决方案是在发送每个响应后关闭服务器上的流,并在收到每个响应后在客户端创建一个新请求(菊花链)。
请参阅我的纯 Tomcat 示例: http://sublemon.com/blog/?p=10< /a> .
I too am unhappy with Chrome's behavior.
My solution was to close streams on the server after sending each response, and creating a new request on the client-side after each response received (daisy-chaining).
See my pure-Tomcat example here: http://sublemon.com/blog/?p=10 .