Socket.io not working in some browsers

Hello everyone.

Socket IO

I've used socket.io in several personal projects. I like it because once you manage to make it work, the next time it's just 15 minutes with the whole installation process and everything.
It solves the problems related to the realtime delivery of messages and does it well.
But as everything else does it has some problems. One of them is that it's not working properly on Safari for Windows and some other specific combinations of Browser [version] + OS.

Going away from what is said on the project's home page - that it is with full fallback support and so on. After a week of investigating what the problem is I finally found that the WebSockets actually have 2 implementations.
The first is uni-directional and is still present in some browsers while the second is bi-directional.
In the first, sending data from A to B and backwards has to be done using two different connections.

So the socket.io supports websockets but it needs the bi-directional version.
According to this article (and not only) http://stackoverflow.com/questions/17849517/check-to-see-if-websocket-is-hixie-client-side there are browsers that support only the first one. So when the socket.io asks them if they support WebSockets they say "Yes." after which they are able to only receive or emit events but not both.

Luckily when requesting to connect to the server we can tell it in what way we want to communicate by passing an array of prioritized connection mechanisms.
So we can say: var sio = io.connect(url, {transports: ['websocket', 'xhr-polling']}); and we are going to connect using WebSocket first and if it fails - with XHR-Polling.

It seems natural to us that if the browser uses uni-directional WebSocket socket.io will fallbacks to the XHR-Polling. But it doesn't.
So we need to fix it manually and here is how.

var transports = {};

if("WebSocket" in window && WebSocket.CLOSED > 2) { // if modern browser
    transports = {transports: ['websocket', 'xhr-polling']};
}else{ // else fallback
    transports = {transports: ['xhr-polling']};
}

var sio = io.connect(url, transports);

This code fragment checks whether the browser supports WebSocket and if yes - if the CLOSED state is greated than 2 (the old CLOSED state was 2, the new is 3 currently).

And only if these two conditions are satisfied - WebSockets are used.

Here's a great table http://caniuse.com/#feat=websockets showing where we are able to use the bi-directional WebSocket connection and respectively - where we should fallback to the uni-directional.

Lucky giraffe