faye/faye — pull request #299 by Intrepidd (2014-05-23 10:01:21+00:00)
Title: Make Faye.Transport.get callback one one transport is found

While integrating Faye into our product, we noticed an issue with how transport switching was done between the handshake and the first subscribe.

Basically, it seems that ``Faye.transport.get`` is selecting the transport asynchronously, while it may be fast for the first transport selection before the handshake, testing if websockets are available seems to take some time.

The problem we identified is the following :

After the handshake, Faye was launching a callback-polling request with /meta/connect, timing out after 25 seconds.
However, meanwhile, it was also opening a WebSocket connection and speaking on it.

# Logs

````
[Faye.Client] New client created for "http://127.0.0.1:9290/faye"
[Faye.Client] Initiating handshake with "http://127.0.0.1:9290/faye"
[Faye.Client] Selected "callback-polling" transport for "http://127.0.0.1:9290/faye"
[Faye.Client] Passing through "outgoing" extensions: {"channel":"/meta/handshake","version":"1.0","supportedConnectionTypes":["callback-polling"],"id":"1"}
[Faye.Transport] Client undefined sending message to "http://127.0.0.1:9290/faye": {"channel":"/meta/handshake","version":"1.0","supportedConnectionTypes":["callback-polling"],"id":"1"}
[Faye.Transport] Client undefined received from "http://127.0.0.1:9290/faye": [{"id":"1","channel":"/meta/handshake","successful":true,"version":"1.0","supportedConnectionTypes":["long-polling","cross-origin-long-polling","callback-polling","websocket","eventsource","in-process"],"clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","advice":{"reconnect":"retry","interval":0,"timeout":25000}}]
[Faye.Client] Passing through "incoming" extensions: {"id":"1","channel":"/meta/handshake","successful":true,"version":"1.0","supportedConnectionTypes":["long-polling","cross-origin-long-polling","callback-polling","websocket","eventsource","in-process"],"clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","advice":{"reconnect":"retry","interval":0,"timeout":25000}}
[Faye.Client] Handshake successful: "n580x011q4hd6xgdxggw98zw9l7bkwb"
[Faye.Client] Calling deferred actions for "n580x011q4hd6xgdxggw98zw9l7bkwb"
[Faye.Client] Initiating connection for "n580x011q4hd6xgdxggw98zw9l7bkwb"
[Faye.Client] Passing through "outgoing" extensions: {"channel":"/meta/connect","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","connectionType":"callback-polling","id":"2"}
[Faye.Transport] Client "n580x011q4hd6xgdxggw98zw9l7bkwb" sending message to "http://127.0.0.1:9290/faye": {"channel":"/meta/connect","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","connectionType":"callback-polling","id":"2"}
[Faye.Transport] Client "n580x011q4hd6xgdxggw98zw9l7bkwb" received from "http://127.0.0.1:9290/faye": []
[Faye.Client] Selected "websocket" transport for "http://127.0.0.1:9290/faye"
[Faye.Client] Client "n580x011q4hd6xgdxggw98zw9l7bkwb" attempting to subscribe to "/all"
[Faye.Client] Passing through "outgoing" extensions: {"channel":"/meta/subscribe","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","subscription":"/all","id":"3"}
[Faye.Transport] Client "n580x011q4hd6xgdxggw98zw9l7bkwb" sending message to "http://127.0.0.1:9290/faye": {"channel":"/meta/subscribe","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","subscription":"/all","id":"3","signature":"9311db694cf41cefa722cdd1f166a63d6b36690a"}
[Faye.Transport] Client "n580x011q4hd6xgdxggw98zw9l7bkwb" received from "http://127.0.0.1:9290/faye": [{"id":"3","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","channel":"/meta/subscribe","successful":true,"subscription":"/all"}]
[Faye.Client] Passing through "incoming" extensions: {"id":"3","clientId":"n580x011q4hd6xgdxggw98zw9l7bkwb","channel":"/meta/subscribe","successful":true,"subscription":"/all"}
[Faye.Client] Subscription acknowledged for "n580x011q4hd6xgdxggw98zw9l7bkwb" to ["/all"]
Subscribed to /all
````

# Screenshots

/meta/connect done via callback-polling :

![screen shot 2014-05-23 at 11 53 38](https://cloud.githubusercontent.com/assets/803765/3065306/65b00738-e260-11e3-81bb-7bf23650d47e.png)

Response from faye :

````json
__jsonp2__([
{
"id":"2",
"clientId":"nbrt4c5evhk06hf2mfz12k8zol03blx",
"channel":"/meta/connect",
"successful":true,
"advice":{
"reconnect":"retry",
"interval":0,
"timeout":25000
}
}
]);
````

Meanwhile, on the websocket :

![screen shot 2014-05-23 at 11 54 08](https://cloud.githubusercontent.com/assets/803765/3065309/72b86d9e-e260-11e3-938f-9ec2629e7db3.png)

# Fix

To fix this, I've added a ``callback`` and a ``context`` param to the ``_selectTransport`` method, and I've wrapped the related actions on the callback in the ``handshake`` method.

This way, we are sure the transport was properly selected when we reach the subscribe method.

Specs run fine and it's working fine on the browser as well.

Cheers,