Tuesday, October 12, 2010

Access to WebSockets on a Sub-Domain though a Proxy iFrame

One of the current design mistakes of Streamie is that the WebSocket server is hosted on the same domain as the main web server. At first this seems like a good idea and the HTTP-upgrade-style implementation of web sockets seem to be made for this approach. Here is why this is still a bad idea:

Scaling web servers is a different task from scaling web socket servers (e.g. because HTTP is inherently stateless while web sockets are inherently stateful and many other reasons). Thus my recommendation is to always host your web socket service on a different domain to enable hosting it on a different infrastructure.

Problem:
While native web sockets make cross domain access easy this is no longer true when you start using all the work arounds (e.g. by using socket.io) like XHR long-polling, multi-part XHR and html-files.
It is important to note that even for clients that do support web sockets often you cannot use them because popular web proxies such as squid do not support web sockets.

Solution:
Access your web socket service through a proxy iframe. This invisible iframe is hosted on the domain of your web socket server and is embedded in your main page. Then access the iframe though the use of document.domain or postMessage. A similar technique (albeit not actually for accessing web sockets is being implemented by #newtwitter. See the source and look for an iframe to api.twitter.com)

6 comments:

Kris Kowal said...

Thanks.

V1 said...

I haven't got any issues with cross domain web sockets so far.. I'm able to connect to socket.io from every domain using websockets.

Websockets are crossdomain so, i don't really see the issue here.

Anonymous said...

That is probably because socket.io will fall back to non-websocket JSONP long-polling for cross domain requests.

V1 said...

@anonymouse no, it's using web sockets. No fallback method.

Malte said...

You are right about the cross origin web socket calls, but see also the update to my post.

cgbystrom said...

Knowing that accessing WebSockets even works through an iframe is good to know, thanks.

Also agree with you that WebSocket servers are scaled very differently from normal web servers. Experienced that first hand in a couple of projects.

Regarding XHR fallbacks, for Beaconpush, we have a Flash fallback as the last resort if everything fails. This allows cross-domain to go through every time (given the user has Flash) since Flash allows cross-domain requests.