websocketpublish-subscribejuggernautbayeuxsocket.io

Faye vs. Socket.IO (and Juggernaut)


Socket.IO seems to be the most popular and active WebSocket emulation library. Juggernaut uses it to create a complete pub/sub system.

Faye is also popular and active, and has its own javascript library, making its complete functionality comparable to Juggernaut. Juggernaut uses node for its server, and Faye can use either node or rack. Juggernaut uses Redis for persistence (correction: it uses Redis for pub/sub), and Faye only keeps state in memory.

  1. Is everything above accurate?
  2. Faye says it implements Bayeux -- i think Juggernaut does not do this -- is that because Juggernaut is lower level (IE, I can implement Bayeux using Juggernaut)
  3. Could Faye switch to using the Socket.IO browser javascript library if it wanted to? Or do their javascript libraries do fundamentally different things?
  4. Are there any other architectural/design/philosophy differences between the projects?

Solution

  • Disclosure: I am the author of Faye.

    1. Regarding Faye, everything you've said is true.
    2. Faye implements most of Bayeux, the only thing missing right now is service channels, which I've yet to be convinced of the usefulness of. In particular Faye is designed to be compatible with the CometD reference implementation of Bayeux, which has a large bearing on the following.
    3. Conceptually, yes: Faye could use Socket.IO. In practise, there are some barriers to this:
      • I've no idea what kind of server-side support Socket.IO requires, and the requirement that the Faye client (there are server-side clients in Node and Ruby, remember) be able to talk to any Bayeux server (and the Faye server to any Bayeux client) may be deal-breaker.
      • Bayeux has specific requirements that servers and clients support certain transport types, and says how to negotiate which one to use. It also specifies how they are used, for example how the Content-Type of an XHR request affects how its content is interpreted.
      • For some types of error handling I need direct access to the transport, for example resending messages when a client reconnects after a Node WebSocket dies.
      • Please correct me if I've got any of this wrong - this is based on a cursory scan of the Socket.IO documentation.
    4. Faye is just pub/sub, it's just based on a slightly more complex protocol and has a lot of niceties built in:
      • Server- and client-side extensions
      • Wildcard pattern-matching on channel routes
      • Automatic reconnection, e.g. when WebSockets die or the server goes offline
      • The client works in all browsers, on phones, and server-side on Node and Ruby

    Faye probably looks a lot more complex compared to Juggernaut because Juggernaut delegates more, e.g. it delegates transport negotiation to Socket.IO and message routing to Redis. These are both fine decisions, but my decision to use Bayeux means I have to do more work myself.

    As for design philosophy, Faye's overriding goal is that it should work everywhere the Web is available and should be absolutely trivial to get going with. I'ts really simple to get started with but its extensibility means it can be customized in quite powerful ways, for example you can turn it into a server-to-client push service (i.e. stop arbitrary clients pushing to it) by adding authentication extensions.

    There is also work underway to make it more flexible on the server side. I'm looking at adding clustering support, and making the core pub-sub engine pluggable so you could use Faye as a stateless web frontend for another pub-sub system like Redis or AMQP.

    I hope this has been helpful.