An important feature of any comprehensive Comet framework is cross-site support. Cross-site capabilities can be particularly beneficial to Comet applications for a couple of reasons. First, keeping a connection open using an alternate host helps alleviate the connection limit problem since the Comet connection does not count against the connections used for same origin requests. Second, it is common to use a dedicated Comet server that is separate from the main application server that handles most requests. The dedicated Comet server can reside at a different host name or port and the browser can directly communicate with it. Consequently, cross-site capabilities tends to be a more important issue for Comet applications than simple Ajax applications.
The most popular form of cross-site communication is JSONP, which is the convention for using script tag insertion with a callback function. This technique is works on all browsers and is relatively efficient, but it has it’s drawbacks as well. JSONP is completely insecure. This may not be an issue if you are connecting to a trusted server (like your own Comet server), but if you are connecting to third party server, at any point they can deliver a script with unattenuated access to your page (DOM access, modification, cookie access, etc.). JSONP also has no support for streaming, all responses must be completely finished before they can be read, at which point a new request must be sent to listen for the next message. Fortunately, there is an expanding set of options for cross-site communication that can be used for Comet.
Native Cross-Site XHR Support
Cross-frame messaging using the postMessage API is available in the current and next releases of browsers. Opera 9 and FF3 already have it, and we will see it in IE8 and the next version of Safari as well. With cross-frame messaging, a separate frame is used as a proxy for communicating with the target server. The requesting frame can load the proxy frame which can communicate easily with the target and then relay messages back and forth between the requesting frame and the target server. There are additional benefits with this approach in that the proxy frame can do client side mediation of messages. For example, in some situations the proxy may be able to immediately respond to a message without having to wait for communication with the server, or it may provide some authorization interaction with the user.
Recently we demonstrated the window.name technique for communicating with servers via a proxy frame that can relay information back to the requesting page via the window.name variable. This technique preserves the security of keeping the target requests in an iframe sandbox, while still allowing cross-site data retrieval. This mechanism also works on all popular browsers.
A common technique for accessing cross-site data with Ajax applications is by proxying requests through the origin server. This is almost never useful for Comet applications. This technique causes the requests from the browser to still utilize the same host name and does nothing to alleviate connection limits. This technique also requires significantly more complex proxying techniques on the server to avoid excessive thread utilization.
WebSocket is almost certainly the most comprehensive solution for Comet. Not only does WebSocket provide full asynchronous duplex streaming communication with a single TCP/IP connection, it also can easily be used for cross-site communication; WebSocket does not carry any of the legacy security problems of cross-site HTTP that have created such extensive restrictions on XHR’s cross-site capabilities. However, WebSocket with full cross-site capabilities also does not have any native browser implementation yet. I would expect to see this in the generation of browsers after next (FF4 or FF3.2, IE9, Safari.next).
This was the original Comet protocol developed in HTML 5. Server-sent events would have cross-site capabilities through the same access control mechanism as used by XHR. However, with the lack of any current browser implementation of server-sent events except by Opera, and the addition of WebSocket in HTML 5 with effectively a superset of capabilities, it is hard to tell if and when this will ever be implemented by other browser vendors.
|Cross-site Transport||Streaming Support||Secure||Browser Support|
|Cross-site XHR||Yes||Yes||Next generation|
|window.name||No (and extra overhead per message with frame setup is incurred)||Yes||All|
|Cross-frame messaging||Yes||Yes||Latest version of browsers (next for IE and Safari)|
|WebSocket||Yes, full duplex!||Yes||Generation after next|
|Server-sent events||Yes||Yes||Opera, but unknown for other browsers|
Dojo 1.2 includes a new XHR transport registry that should make it much easier to utilize these new transports for Comet applications. It will now be possible to register that a server supports a particular transport, and Dojo can automatically utilize this transport when available for
dojo.xhr() is utilized by Dojo’s Cometd client implementation in the long-polling transport, and it is also used by the REST Channels module. Currently the Cometd server implementations only support JSONP, but adding support for new transports as they become more widely available will probably be quick and easy. I have added support for the window.name transport in Persevere, and you can see a simple demonstration of cross-site Comet using this transport. This transport is a little slower than JSONP, but it has the advantage of being secure (the target site can not exploit the requesting site). Note:Orbited directly exposes the WebSocket API in their Comet implementation, making it easy for Orbited users to switch to using the native WebSocket API once implemented by browsers.
The emerging options for cross-site communication should certainly benefit Comet applications. Developers have a greater selection of tools available to them, and with a proper understanding of the transports, developers can usually find an efficient mechanism for their application.