Comet Jetty/Tomcat, having some browser issues wit

2020-07-22 19:04发布

问题:

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:

  1. 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.

  2. 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

回答1:

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.



回答2:

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 .



回答3:

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.