Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Socket.IO P2P (socket.io)
180 points by Rauchg on July 15, 2015 | hide | past | favorite | 27 comments


It'd be nice if the socket.io project spent less time adding features and more time just documenting what they have.

Does anybody have a small, fast, no-bullshit, modern websockets library they'd nominate for use with node?


Absolutely! I've had terrible experiences with vanilla socket.io regarding reconnections, performance, and reliability. This is even after the 1.0 release.

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.

[1] https://github.com/primus/primus


Agreed. Mostly quoting myself from earlier this year: I don't normally like bashing open-source projects, but socket.io should not be used. It may be noob-friendly, but that's just because it does things so automatically that you can't really use it correctly. When I was a websockets noob, I used socket.io briefly, and it was a complete waste of time.

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.


+1 for Primus. We moved to it on BitMEX from a custom SockJS + Mux-demux setup and the transition was painless. We now get the ability to change transports based on client (so our API clients get the very fast standards-compliant node `ws` library, while browser clients get engine.io). We also gained reliable heartbeating which was a big win.

I've found the devteam to be really responsive and their choices of abstractions appear to work well.


I moved to SockJS [1]. Socket.io itself was great but I had serious trouble to get socket.io server (gevent-socketio) working with Python and Flask.

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/


We use ws(https://github.com/websockets/ws) in prod. Clean, fast, and simple. Plus it supports browsify using native implementation but wraps it to fit the server side api.


SockJS is definitely a reasonable choice as a base. At Pusher we use a fork of SockJS for HTTP fallback but we actually use em-websocket [1] (ruby) for our WebSocket API. Given the opportunity we'd probably move away from SockJS to something much simpler because we only want the HTTP fallback part and it only handles < 8% of our connections.

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


We're lucky in that we require web workers, so we get web sockets compliance for free. We also are an infrastructure deployment, so we get some leeway in ignoring shitty devices.

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.


Lucky indeed! I've been pushing for us to drop IE7 (and maybe 8) so we can move to more modern tooling and libraries as part of the development process. But customer requirements mean we've got to stick to IE7 for now.

EDIT: But this is an important factor for dev in general http://www.w3.org/TR/html-design-principles/#priority-of-con...


What's great about SockJS is it's meant as a WebSocket polyfill and nothing more. It also has some semblance of a protocol definition. This makes it an ideal foundation to build upon if what you really want is WebSockets, but you need a bandage for old browsers.

Meteor notably uses SockJS as part of their DDP spec.

Also Pushpin includes a SockJS to native WebSocket translator.


It does seem to be the most commonly used WebSocket polyfill around. We also use web-socket-js [1] for fallback. But Version 3.0 of pusher-js [2] will remove that.

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


The problem is that even if XHR is on a local domain and ensured to work, long-polling is still more intensive than, for example a persistant frame, because you have to re-establish a new connection after each message, even if you bundle messages to a one second window, it's still got the overhead of a new connection (and the latency involved therin) which is even longer if HTTP2/SPDY + SSL.

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.


The overhead of long-polling isn't quite so bad in practice thanks to persistent HTTP connections, where an existing TCP connection is reused for future HTTP requests. Pretty much all browsers support this, and so a re-poll is usually 1 packet.

Of course, long-polling is still more overhead than a streaming connection.


Same bad experience here with socket.io.

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.


How are you scaling it? I'm using the Ruby version along with eventmachine but max concurrent connections was 1024.


sounds like you're hitting the ulimit for your server process, rather than a issue with Faye itself.


I use [ws](https://github.com/websockets/ws). I've never had any trouble with it, and it benchmarks well. Of course, there's no fallback there; just websockets.

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.


Personally I think PeerJS is a much more mature, robust and better documented solution.

http://peerjs.com/

Last time I checked PeerJS also provides support for handling TURN/ICE/STURN.


What's the state of this project? This issue seems to suggest the project is dead. https://github.com/peers/peerjs/issues/290


Is it documented anywhere how they handle TURN/ICE/STURN for dealing with firewalls and routers?

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 :(



I'm humored by the fact that this example isn't working for me.


Too bad the demo doesn't work, I was really excited for this. Regardless, big congratulations to the Socket.IO team for an awesome feature! And props to Feross for his simple-peer module, he is doing incredible work in the WebRTC world.

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!


Neat, when can we expect a DHT (distributed hash table) for decentralization? ;)



I'm working on something like this as a solution, though I think you want/need federated tables with a global namespace.


Can I use this to send udp+tcp between clients and servers?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: