Socket.IO P2P
socket.io
socket.io
Does anybody have a small, fast, no-bullshit, modern websockets library they'd nominate for use with node?
Lately, I've been using primus [1], which is an API unification layer for socket.io, sockjs, faye, and native websockets. Swapping one engine for another is trivial, and they've taken pains to abstract a core subset of functionality.
See, for example, https://github.com/Automattic/socket.io-client/issues/572 (closed without comment).
SockJS is much better, as is raw websockets. Presumably Primus, too, although I'm a bit surprised that one can come up with a sensible interface that can be layered over both Socket.io and anything else.
I've found the devteam to be really responsive and their choices of abstractions appear to work well.
SockJS has a decent JS client-lib and a good set of server counterparts. Node, python, erlang and java (using Vert.x).
Vert.x [1] combined with SockJS is especially powerful -- vert.x supports so called 'verticles' in multiple languages (JavaScript, Ruby, Java etc) that are running as tiny servers who can communicate over eventbus. Then the SockJS lib can be used to handle communication between the browser and Vert.x eventbus.
Probably not intended but I'm also using SockJS to communicate events between a Flask app in python and Vert.x java verticle.
[1] https://github.com/sockjs/sockjs-node
[2] http://vertx.io/
If you _only_ want WebSocket connections with no HTTP fallback then Faye WebSocket [2] may be an option. But any production application is going to require fallback for older browsers and pesky proxies/firewalls.
Faye [3] is solid (obviously used Faye WebSocket), has implementations in Node and Ruby, but is a PubSub solution. I'd kinda argue that any real-time app needs at least PubSub functionality anyway.
The ws Node module [4] is apparently "The fastest RFC-6455 WebSocket implementation for Node.js" and receives contributions from 3rd-Eden who is also behind Primus [5]. But it's also WebSocket with no fallback.
I haven't used Primus, but I really like the idea of offering a layer above the underlying connection engine. I've seen contributions to Socket.IO dip in the past (prior to CloudUp being acquired by Automattic), but Socket.IO is used by so many apps that somebody is always likely to maintain it for the foreseeable future. I'm generally in favour of adding abstractions around layers like this (connectivity, DBs, Message Queues, Hosted Services etc.). However, in this case you're then adding a dependency on Primus. Isn't software fun!
[1] https://github.com/igrigorik/em-websocket [2] https://github.com/faye/faye-websocket-node [3] http://faye.jcoglan.com/ [4] https://github.com/websockets/ws [5] https://github.com/primus/primus
I made the decision early on to push on the business side as hard as possible to only use modern web tech, and it has saved us a lot of trouble. HTML5, without compromise, is nice.
EDIT: But this is an important factor for dev in general http://www.w3.org/TR/html-design-principles/#priority-of-con...
Meteor notably uses SockJS as part of their DDP spec.
Also Pushpin includes a SockJS to native WebSocket translator.
One negative with SockJS has been the complexity of the fallback approach on the client (the browser). Especially when it's only for 8% of connections. A single simple cross-browser HTTP-based transport would remove the code complexity and reduce the file size.
[1] https://github.com/gimite/web-socket-js [2] https://github.com/pusher/pusher-js/tree/r3.0.0
Of course, that may well be enough for some situations, for others, there's too many server-pushed messages to keep up with that model as well.
Of course, long-polling is still more overhead than a streaming connection.
I switched to Faye (http://faye.jcoglan.com/) an implementation of Bayeux protocol programmed by James Coglan. I'm using the node version of the library in my games for 4 years with excellents results.
I haven't seen a websocket+fallback lib that seems like it will work well. Requiring sticky sessions and disallowing using node's cluster module is the norm, and neither of those are appealing. We've rolled our own polling fallback, which is also used to cleanly handle missed messages during a websocket reconnect.
Last time I checked PeerJS also provides support for handling TURN/ICE/STURN.
EDIT: Looks like it doesn't. This is basically just a very small library on top of socket.io. Look forward to them helping solve the TURN/ICE/STUN issues :(
In other news, to address some of the comments here:
- As others have mentioned, https://github.com/sockjs is an alternative that is more lean with less features.
- I've also written an inverse websocket tool that behaves like a regular HTTP request/response, but will proxy it through WebSockets or fallback to JSONP. I really like this approach because it feels more RESTful, has less overhead, and even allows the browser to do a `createServer`. It is currently pretty tightly coupled into a project of mine (next bullet), I'll try pulling it out into its own library if there is demand, but here is the source:
- - Client library, https://github.com/amark/gun/blob/master/gun.js#L1138 and onwards.
- - Server library, https://github.com/amark/gun/blob/master/lib/wsp.js#L8 and onwards.
- - Really nifty HTTP normalizer, https://github.com/amark/gun/blob/master/lib/http.js .
- - Really nifty WebSocket normalizer, same format, https://github.com/amark/gun/blob/master/lib/ws.js .
- - Really nifty JSONP normalizer, same format, https://github.com/amark/gun/blob/master/lib/jsonp.js .
- If you do use the P2P Socket.IO feature, the next thing you'll need is a P2P database that can run in the browser! And that is what my main open source project, http://gunDB.io/ is about. The previous bullet's code is my nimble websocket and fallback library I wrote for this project, and that is why they are currently tightly coupled - sorry about that. If there is enough demand for it by itself then I'll try making it into its own library.
Cheers!