Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Introducing Socket.io 1.0 (socket.io)
498 points by rafaelc on May 28, 2014 | hide | past | favorite | 75 comments


I like the separation of the transports into engine.io, however it would be even better if it exposed a standard Node.js Stream interface so that it played nicely with the growing ecosystem of Stream-related modules.

Dominic Tarr, substack, and others have been advocating this idea for awhile: https://github.com/substack/stream-handbook

Gluing together various types of streams and stream transformers is a really nice way to build certain types of applications.

Fortunately it should be easy to write a Stream compatible wrapper.



That probably works fine, but if it's encapsulating a stream over Socket.io's protocol then it's going to be much less efficient than the other way around.


You could also just use Primus which exposes a Stream compatible wrapper by default for the client and server.

https://github.com/primus/primus

(Primus uses engine.io,sockjs,browserchannel,websockets internally so you're no longer locked into a specific framework)


someone should do primus vs socket.io

why would I need engine.io,websockets for example when engine.io already uses websockets if it can upgrade the connection to them?


You can't use both. In Primus you can select only one transformer, listed above by V1, but if something doesn't work, you can just switch it with a single line of code. No rewrites, no need to learn a new API.


I know you can't use both, but doesn't engine.io already support websockets?


Yes it does, but if you are building something that works perfectly only using websockets (e.g. a command-line utility), why would you use engine.io?

You can tell engine.io to only use websockets, but what's the point if you can use websockets directly and have the same API?


The undoubtable mention of SockJS will appear multiple times in this thread. Socket.io has been plagued with scalability issues since its original release (can't speak on the new version) and Engine.io is suppose to be fix that. The main difference between SockJS & Socket.io is their connection establishment. SockJS begins by attempting to use Websockets and regress to long polling while Engine.io starts with long polling and slowly works its way up to Websockets.

For a good debate on this with the creator of SockJS: https://groups.google.com/forum/#!topic/sockjs/lgzxVnlth54


I second @weixiyen. You bring up "Socket.io has been plagued with scalability" and then elaborate on the irrevalant graceful degradation strategies of each framework


> Socket.io has been plagued with scalability issues since its original release

How does that affect scalability, or how is that related to your comment?


I've since switched to SockJS for all of my projects (after struggling with memory issues in Socket.io 0.9.*). Any compelling reasons to give Socket.io another try?


The new engine.io module used behind the scenes is amazing. It will start with long polling, and upgrade to WebSockets seamlessly (so you get a very fast start every time, even in old browsers or proxied envs). AFAIK, this is the opposite of what was happening previously (trying WebSockets, then falling back to long polling). Engine.io is also much more scalable and robust.

Disclaimer: I work at Automattic, we've been using engine.io on cloudup.com for a while.


When I switched to SockJS, I tried Engine.io too, but I ended up going with SockJS mostly because Engine.io didn't expose the client's IP address to Node, which made IP banning impossible. It looks like it's still an issue, sadly.


Congrats on the release! I know this was a long time coming.

A scalability question:

You note "Turn on sticky load balancing (for example by origin IP address). This ensures that long-polling connections for example always route requests to the same node where buffers of messages could be stored."

I read this to mean that we are responsible (in our load balancer/proxy/etc) to keep connections from clients returning to the same server. This is OK, but what about nodeJS clusters? How should I ensure that client A always connects to cluster-node member 3?

Related section of the blog post: http://socket.io/blog/introducing-socket-io-1-0/#scalability


As a note, I switched to Faye for most of my websocket needs because of this http://faye.jcoglan.com/


I tried using faye and it died very quickly under load with the redis backend. For every message that you send it queues it up into a redis list for each faye server in the cluster to read which doesn't scale very well in their very chatty redis queue system.

I would do significant load testing for each use case before using it (or socket.io for that matter). I needed to push 30-50 messages per second to each connected client and faye started choking as soon as there were more than 20-30 clients. socket.io would choke at around 50-100 connected clients. Raw websockets were able to reach closer to 100 clients but performed more or less similar to socket.io.


That's an incredibly high rate of messages. What could you possibly need that many messages for? I'm in no way surprised that generic solutions don't work for your case.


This: https://map.couple.me

We kept the design simple, otherwise a "batching" mechanism could be introduced that would replay a single batch of 50 messages but that would make everything a second delayed. However, part of the map allows you to login and see your messages live on the screen as you're sending them to your partner and for that the real time streaming is pretty critical.


It looks like you're sending the same data to every client, but it sounds like Socket.IO/Faye aren't handling this well. Do they not have a `broadcast` method of something of that nature that handles your use-case?


I love Couple, I was looking at this map earlier this week actually. Very interesting to read how you made it work, thanks for sharing.


The node.js cluster module is not flexible enough to be used with engine.io / socket.io / sockjs etc. Just run several processes and put something like HAproxy in front of them. If using a cookie to ensure stickiness, you can scale to multiple load-balancers easily.


That seems like a pretty big requirement that could frequently be deal-breaking. I would expect a big warning somewhere that you can't cluster if you're using socket.io.


I concur; we use sticky-sessions in our load-balancer, and stunnel when we're doing it on an SSL'd page, and it's working just fine.


This was a long time coming! I'm very happy to see socket.io 1.0 finally released. Pre-1.0 had some deal-breaking technical issues, such as starting with websockets and falling back to polling. I think the new approach is starting with polling and then seeing if a) websockets are supported by the current browser and b) messages sent via websocket are received by the server (a firewall might prevent this).


Have you guys dealt with the 3-year clustering bug? https://github.com/Automattic/socket.io/issues/438

Would be pretty hesitant to use it until there's some sort of closure on this.


Please read the "Scalability" section on the blog post! This very demo is fully clustered.


Its dependent on sticky load balancing - a pretty big caveat. And as far as I can tell, it still doesn't work with the cluster module, which is what that issue is about.


It appears that the answer is "kind of". You can't use cluster, but you can put multiple processes behind a load balancer if the load balancer can do sticky routing. They should probably be a lot more explicit about this; the scalability section seems to avoid mentioning that socket.io isn't compatible with the cluster module.


Sticky load balancing was a deal breaker for us when we built the https://map.couple.me visualization with socket.io. At the last minute I just pulled older browser support and left it with raw websockets instead of socket.io because the cluser module couldn't be used otherwise.

We had two issues with sticky load balancing:

1. AWS ELB had to run in TCP mode (for websockets) which meant no stickiness

2. Within each instance we have a node-cluster running to utilize multiple CPUs and putting haproxy with stickiness there increased complexity

We could avoid using the ELB but then you lose the ability to use an EC2 Auto Scaling group, introducing significant admin overhead.

Ultimately we didn't need the nodes communicating between each other (it's a one way stream from us to the client) so raw websockets ended up being the simplest solution.


Something about this site just kills both Firefox and Chrome on my Windows 7 computer: everything becomes choppy and laggy, even outside the browser. On both browsers, things return to normal when I close the tab.

Task Manager shows no unusual CPU activity beyond the initial page load.


It's almost certainly the multiple animations (<video> elements) on the page.


I'm having the exact same issue.


I've used Socket.IO quite a bit, congrats on shipping! Did the issue/"lack of feature" get fixed where not all transport methods fire a disconnect event? That was especially a pain on a recent project, ended up forcing websocket only to get around it. EDIT: Ack, I should probably clarify this better. The issue is that a client disconnected is not determined by the server. The server waits for the client to send a disconnect event to it prior to leaving the page. This is particularly a problem on iPad where the event will not fire for certain transports so disconnect doesn't fire when you shut off an iPad unless websockets are actively used.


I solved this by firing an event on window.beforeunload. Had the same issue.


You need mandatory ACKs in both directions if you want to implement a reliable stream over HTTP requests. Otherwise, data can get lost in several scenarios, including: server responds to a long-poll request, connection breaks before client receives it, server assumes the data arrived, user never sees the message. Instead of having an ACK for every message in both C2S and S2C directions, socket.io implements some kind of bizarre optional-per-message ACK functionality that you manage with callbacks. There are libraries/protocols that do this right, including Closure Library's BrowserChannel.


How does the binary support/performance and streaming support (with socket.io-stream) compare to other web socket libs like https://github.com/binaryjs/binaryjs, https://github.com/einaros/ws and https://github.com/maxogden/websocket-stream ?


Congrats for the release, but i will keep using https://github.com/primus/primus.

No module lock-in!

Yes i'm a bit biased.


I knew things were changing in 1.0, but there are a lot of things mentioned in that blog post that seriously make me giddy. I'm really, really excited to play with this tonight.

Also, incredible job on the new website. Seriously love it. All around great work, if there was a Gittip button on the website I would have already clicked it.


A kind of OT question related to socket.io.

I am trying to develop an application that can be horizontally scaled. I understand using the socket.io-redis package seems to allow you to emit to a particular socketid from one instance while that connection itself is connected to another machine and the redis connection will take care of the communicating. This in a sense abstracts away the fact that there are multiple servers by just taking care of it transparently.

Are there any provisions within socket.io or another package that allows you to sync normal js objects across servers as well? The alternative as I see it is to use redis pub/sub to keep the state in sync but this feels like it should be a solved problem that one need not reinvent the wheel for.



Thank you, will check it out


I wish there was more info on the CS 1.6 demo, is there an address to look at it?

EDIT: found it at http://socket.io/demos/computer/


That iframe is simply pointing to http://socket.computer (yes, the new .computer TLD is here)


This is exactly how I've always wanted the web to work. i've spent some time with socket.io working through "nodejs in action" and I can't wait to use it for new apps.


Finally!! I was going to switch to naked engine.io because it can handle many more connections without going crazy. Now I can get it without changing my code. Woo hoo!


This seems like a good place to ask: Does anyone know of a library (preferably C++/Emscripten) that simplifies using WebRTC to create real time network games?


I looked for a library for a similar WebRTC project. All of the libraries I found contained superfluous functionality, as I was only interested in data channels and did not want to be locked in by a particular third party. I ended up rolling my own; the WebRTC API is simple enough [1] and there is some example code from Google that points the right direction [2]. Additionally, Socket.io makes for a convenient signalling server prototype, though it is overkill.

[1] http://dev.w3.org/2011/webrtc/editor/webrtc.html

[2] https://bitbucket.org/webrtc/codelab


You might also find something useful at http://bit.ly/webrtcwebaudio. PeerJS is a library oriented to data exchange: http://peerjs.com.


If you want a simpler signaling server for WebRTC, you might check out the "caress" server I developed for Chatphrase: http://github.com/chatphrase/caress


If it fits your needs why not Socket.io? They now support redis emission which means all these langs work: http://redis.io/clients


I'm really excited about this.

Anyone know of any projects working towards getting this new version to work on native iOS/Android?


demo on http://socket.computer - err, I knew new TLDs might be fairly annoying but didnt think they would totally break my brain's URL parser.

At first I thought that the article's author forgot to replace an intranet link.. nope its a new tld here to mess with our heads!


Sadly TLDs are really getting out of hand. I was notified today that .ninja is now available. This coupled with Dr. Dre potentially joining the Apple board and the TrueCrypt announcement has made for a pretty surreal day in tech news.


As I understand if I want to use socket.io client API I have to run node.js as a container for socket.io server side code and then I can create a new emmiter for my server language (similar to PHP example in the article) Is it correct?

Is it possible to create own implementation of socket.io server side code?


Seems pretty good, and faster than the previous version, but:

- Changed some things (method names, and so on) with no reason - It's not possible to use a custom logger anymore - I can't access the list of rooms anymore (or it changed and they didn't documented it yet)

Somebody else ?


I've been using engine.io directly in production for quite a while, and it's been stable and reliable. Glad to see this release, having the option of going back to the higher-level socket.io api is welcome.


Excellent news, looking forward to using it. socket.io is awesome !


Might I suggest you not hijack the "DEBUG" environment variable? It will almost certainly cause issues down the line when you could be using SOCKETIO_DEBUG.


DEBUG is not solely used by socket.io, but rather by all modules that make use of the `debug` node package:

https://github.com/visionmedia/debug

The DEBUG variable holds a comma separated list of names (or wildcard patterns) used to narrow the scope of the debug output.

For example, to get debug information about the internal components of socket.io and express, you could do:

DEBUG=socket.io:,express: node index.js

There really isn't a big chance of hitting problems with the DEBUG variable, since it's defined locally to the command and not exported, and there's already a reasonably well established convention of using it like that for node modules.


This library was intuitive enough to learn in a few hours and allowed me to make a fun toy project in half a day. Highly endorsed.


>The Socket.IO Server is now only 1234 lines of code

I prefer to think in standardized terms like KBs, not lines of code.

EDIT: For the downvoters, I am just saying that it would have been more beneficial to myself had they of addressed their improvement in terms of a percentage of code reduction or actual measurable size of their code. I was not trying to be snarky.


Great.

offtopic: please fix your blog, it breaks the browser history in IE 11 (spammed with hash entries)


As long as we're off topic, I think the OP means to say that

"The benefits of this particular modularization can’t be overstated"


It sounds like Automattic deserves some thanks for their support on this. Thank you.


They do. Worth noting that A8C acquired our company LearnBoost/Cloudup in 2013, where we had built/supported Socket.IO and many other Node.js libraries for the prior +3 years


wow that is cool. last time I tried it I had a hard time struggling with HAProxy and trying to fix the sticky session thing.

Would be great to see some benchmark of how this can scale especially with the new redis integration.


Finally! It's been a long time coming. Thanks for your hard work!


woah, the weplay pokemon node.js emulation's chat [0] is off the chain. Everyone controls the guy and the cursor.

[0] http://weplay.io/


I've been waiting for this for so long. Thanks Guillermo!


Awesome!!! Can't wait for the future of IO.


Congrats Guillermo and everyone involved!


Congrats Guillermo and gang!


socket.io has 635 open issues. Seriously !


Finally.




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

Search: