Yesterday I published my sample Comet application for WLS 10.3 and described how to get it to work with Dojo 1.1.1. I mentioned that I had an issue with Dojo's brand new 1.2.0 release. Well I figured out the issue and the work-around to using Dojo 1.2.0 with WLS 10.3. All that is required is to call the dojox.cometd.connectionTypes.unregister() function before you use dojox.cometd.init().
dojox.cometd.connectionTypes.unregister("long-polling-json-encoded");
Now that I ruined the punch-line, read-on if you're interested in how the Bayeux protocol handshake happens and how I trouble-shot this. When the client initializes there is a handshake message exchanged with the server so they can agree on which method of communicating to use. Apparently WLS 10.3 as it ships does not like a new supported connection type that is available in Dojo 1.2.0.
The client normally uses code like this to initialize a connection:
<!-- Import Dojo --> <script type="text/javascript" src="dojo-release-1.2.0/dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script><script type="text/javascript">
dojo.require("dojox.cometd");
dojox.cometd.init("cometd");
</script>
Using Firebug and a simple URL decoder we can see that it sends the following with a POST to the server:
message=[{"version":"1.0","minimumVersion":"0.9","channel":"/meta /handshake","id":"0","supportedConnectionTypes":["long-polling","long-polling-json-encoded ","callback-polling"]}]
The response looks like this:
[{"channel": "/meta/handshake", "successful": false, "error": "402:long-polling-json-encoded:Invalid
supportedConnectionTypes attribute.", "supportedConnectionTypes": ["long-polling","callback-polling"
], "version": "1.0", "minimumVersion": "0.1", "advice": {"reconnect": "none", "interval": 500, "multiple-clients"
: false}}]
Uh oh, notice how there is an error in the handshake indicating that WLS does not like the long-polling-json-encoded connection type? So after posting in the Dojox support forum, I got a response suggesting specifying a property as an argument to the init() call so as not to send the extra connection type. That did not work for me, but it put me on the path of using Firebug, the js source, and the Dojo API docs. I discovered that the connection types are stored in an dojo.AdapterRegistry and that there is an unregister function for the connection types. That's it. So now my client code looks like this with the new unregister invocation:
<!-- Import Dojo --> <script type="text/javascript" src="dojo-release-1.2.0/dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script><script type="text/javascript">
dojo.require("dojox.cometd");
dojox.cometd.connectionTypes.unregister("long-polling-json-encoded");
dojox.cometd.init("cometd");
</script>
Which results in a POST like this:
message=[{"version":"1.0","minimumVersion":"0.9","channel":"/meta /handshake","id":"0","supportedConnectionTypes":["long-polling","callback-polling "]}]
And a successful response like this:
[{"channel": "/meta/handshake", "version": "1.0", "supportedConnectionTypes": ["long-polling","callback-polling"
], "clientId": "NNR2BOeRyCVKjLN", "successful": true, "minimumVersion": "0.1", "authSuccessful": true
, "advice": {"interval": 500, "multiple-clients": false}}]
Which causes the Dojo cometd framework to send another request specifying that it prefers long-polling:
[{"channel":"/meta/connect","clientId":"NNR2BOeRyCVKjLN","connectionType":"long-polling","id":"1"}]
And a confirmation response that long-polling should be initiated:
[{"channel": "/meta/connect", "successful": true, "clientId": "NNR2BOeRyCVKjLN", "error": "", "timestamp"
: "2008-10-22 01:59:27", "connectionId": "null", "advice": {"interval": 500, "multiple-clients": false
}}]
Which results in an immediate call to the server:
[{"channel":"/meta/connect","connectionType":"long-polling","clientId":"lMRDFU5fBxnE5kg","id":"3"}]
The response either times out on the server after about 80 seconds or returns if there is an event that the client has subscribed to sooner. Then the process simply repeats. Here is the response after a timeout.
[{"channel": "/meta/connect", "successful": true, "clientId": "lMRDFU5fBxnE5kg", "error": "", "timestamp"
: "2008-10-22 02:15:57", "connectionId": "null", "advice": {"reconnect": "retry", "interval": 500, "multiple-clients"
: false}}]
This causes the connect message to be sent again. Firebug shows me the spinning request (see the last POST) indicating that it is waiting for the server response, and I know that it's working. And the world is right again. A helpful diagram showing how some of the various delivery methods work for this is on Carol McDonald's blog.

Comments (2)
Hi James,
Nice Blog ! This helped me to develop my own chat application in minutes.
But I am facing an issue. When I deploy my chat.war as part of application ear,
dojox.cometd.init("cometd");
does not work any more. Same works if I deploy the war file outside of the ear.
I have tried putting the context path of war file:
dojox.cometd.init("/testchat/cometd");
But still no luck, while the war is part of application ear file.
Thanks
Siddhartha
Posted by Siddhartha Banik | October 3, 2009 10:44 AM
Posted on October 3, 2009 10:44
Siddhartha,
I'm not sure what would cause that issue with packaging the web module in an EAR to change the application behavior. I recommend a support case as this should be a completely supported configuration.
Good luck,
James
Posted by james.bayer
|
October 6, 2009 1:23 PM
Posted on October 6, 2009 13:23