top | item 6516240

Heroku WebSockets Now in Public Beta

159 points| coloneltcb | 12 years ago |blog.heroku.com | reply

51 comments

order
[+] sync|12 years ago|reply
I wonder how many WebSocket connections one dyno can take?

Also seems like this would make heroku's routing problems[1] even worse.

[1] http://news.rapgenius.com/Jesper-joergensen-routing-performa... et al.

[+] bgentry|12 years ago|reply
> Also seems like this would make heroku's routing problems[1] even worse.

No, this will not make routing issues worse.

The routing issues described in that post specifically apply to single-threaded / non-concurrent applications (or those with very low concurrency, such as Unicorn w/ 2 workers).

WebSocket connections are like requests that last forever. If you're using WebSockets in your app, you'll need your app to be highly concurrent in order to maintain lots of open connections to your users. You don't want regular requests to block behind never-ending WebSocket requests.

Random routing should actually work pretty well on apps with high concurrency. Node.js, Play, Go, Erlang, and even Ruby apps with Faye should all work great.

If you're concerned about this for your app, the best way to find out is to test it!

[+] Touche|12 years ago|reply
Can anyone explain why Heroku had to enable WebSockets in the first place?
[+] bgentry|12 years ago|reply
Since we launched the Cedar stack, we've used AWS ELBs as the front layer in our routing stack. Since we had only ever allowed regular, short-lived HTTP requests through our stack, we opted to use these in HTTP(S) listener mode [1]. When used in HTTP(S) mode, ELBs have historically been very strict about what traffic they allow through.

As the WebSocket standard is very recent, it has never been supported by ELBs in HTTP mode.

ELBs in TCP mode can support any TCP traffic. It's become clear that we need this flexibility, so we're moving to TCP-mode ELBs now. This was not trivial, though, as long-lived connections (like those used for WebSockets) have different implications for our HTTP routers. That had to be taken account.

Nonetheless, we've had a private beta for a long time that worked as described above. But we deemed it insufficient for general customer use because TCP-mode ELBs mean that you lose the client's source IP and protocol. Fortunately, ELBs now have Proxy Protocol support [2], which allows us to keep that request information that Heroku apps typically rely on.

[1] More info on ELB modes: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/Devel...

[2] http://aws.typepad.com/aws/2013/07/elastic-load-balancing-ad...

[+] statusgraph|12 years ago|reply
They're very different from typical HTTP requests: very long lived and generally cannot be buffered.
[+] ikawe|12 years ago|reply
Woohoo! Finally the weiqi on nodejs+socket.io app we built a year ago is ready for prime time:

http://evening-meadow-5281.herokuapp.com/

It's pretty shoddy, but this might give me some inspiration to move forward.

The nice thing about socket.io, is it prefers websockets, but will fall back to long polling if not available on both the client and server.

So this didn't even require a redeploy, just a `heroku labs:enable websockets`

And like magic I can support more than 10 concurrent users ;)

[+] tlrobinson|12 years ago|reply
Is it possible to use something like Socket.io that falls back to long-polling on older browsers?

The biggest problem I've had with Socket.io on PaaS's is it pretty much expects every request from a particular client to be routed to the same backend (i.e. sticky sessions), which works ok with a single backend but obviously doesn't scale.

Given Heroku's stateless routing architecture, I'd guess no, but maybe there's something I'm missing?

[+] philipnuzhnyy|12 years ago|reply
My little weekend project (http://chatzilla.herokuapp.com/) that I put on Heroku a few weeks ago uses socket.io with Flask, gevent and socket.io would automatically fallback to XHR polling. Using socket.io is great for these cases since it's all done automagically.
[+] JimmaDaRustla|12 years ago|reply
Awesome! Maybe I will try out some SockJS on it! I decided last night to use SockJS for a personal web application for streaming some stock analysis.
[+] derefr|12 years ago|reply
Since they're already likely decoding and parsing the websocket protocol to proxy it, it'd be nice if they offered something like "SockJS-as-a-service", where Heroku handles all the different connection termination types, and just exposes a plain websocket (or maybe a raw TCP socket, even!) to your backend.
[+] cmwelsh|12 years ago|reply
What is the average latency for the service?

From my benchmarks, there is a measurable difference between cloud VPS WebSocket latency/bandwidth and dedicated server WebSocket latency/bandwidth.

[+] tlrobinson|12 years ago|reply
With a simple echoing Node.js WebSocket server I'm getting about 50 ms (each way) on Heroku, DotCloud, and Engine Yard. That's probably not much more than the network latency.
[+] xauronx|12 years ago|reply
This is awesome! I was literally working on a project today that needed websockets and I was so bummed out that I had to use Socket.IO and fallback into long polling.

If you Heroku guys are still listening... I'm so fucking impressed that you already updated the docs I was using earlier. I was going to suggest you update them... but then I went to grab the link and it was updated. Well done.

[+] fdr|12 years ago|reply
I'll forward your remarks to the devcenter staff and the steward of the changes; I'm sure both parties will appreciate it a lot.
[+] TomJoad|12 years ago|reply
Any particular reason why blogs.heroku.com would want to know my location? Isn't the IP generally enough?
[+] azinman2|12 years ago|reply
Scroll down and you'll see a geo-demo that is better off with your browsers reported location.
[+] habitue|12 years ago|reply
Whelp, looks like they just killed Pusher: https://addons.heroku.com/pusher
[+] wmf|12 years ago|reply
Good; websockets are a feature not a company.
[+] glenngillen|12 years ago|reply
Not at all, you still need to manage state across processes /dynos. Either you reinvent that yourself and use something like Redis to do it yourself or you outsource it to something like Pusher and relieve the load on your own web service in doing so.
[+] serkanyersen|12 years ago|reply
I needed this feature 1.5 years ago. Thanks Heroku.
[+] zeckalpha|12 years ago|reply
Thanks Amazon.
[+] jlward4th|12 years ago|reply
I've been using this with a Play Framework + Akka + Scala app and it's working great! Thanks Heroku.