You might not need a WebSocket
blog.fanout.io
blog.fanout.io
Websockets suck here. BGP routers here flap very often, nuking TCP connections because hey, power cuts. Guess what happens?
Tip: If you're "out to change the world", make sure you can turn your wifi card every 30 seconds and still get a decent-ish experience (yes, long-polling HTTP works, so does good old timer-based polling).
I lose ssh and my websockets, but long-polling apps keep working. Kind of ridiculous, but that's the world we live in.
Making your websockets resilient means pinging and aggressive reconnecting.
Here's one hosted Etherpad: https://etherpad.wikimedia.org/
And will be launching a web client in the coming weeks.
So far, so good. We do handle the reconnects ourselves, but otherwise it's been treating us well.
Setting an alias like "alias sssh='mosh'" greatly helps with muscle memory, too (of course, don't override "ssh", you might still need it).
Funny anecdote: I live in a city called "Moshi"
\sshOr is it just that long polls generally have short timeout compared with what you might implement for a websocket ping?
Fortunately wrappers like Socket.io, SockJS, Primus, etc can help with this.
Yes it does, but not for the reasons you mentioned. The main objection against long-polling in the olden days was that it would spin up a new server process every time, leading to server overload. Websockets solved this by allowing a single server to handle multiple connections on the same socket.
However, these days that is arguably not the case anymore. I think most servers don't make a new process for every request anymore, but I could be wrong. Am I wrong?
Regardless, long-polling has left a sour taste in people's mouths and now they've moved on.
But I agree, websockets are overkill for most cases and I have personally never found them to be a very reliable piece of technology. They're super fragile and finnicky and I never liked working with them.
That's correct. Most designs use either a prefork model (e.g. Apache) or an asynchronous event-driven model (e.g. Nginx). With prefork, a number of worker threads or processes are created on start up, and each services one request at a time. In the asynchronous model, a smaller number of (typically single-threaded) processes are created on start up, and each services one event at a time. An event could be an incoming request, a database query returning, etc. In either model, thread/process creation typically happens entirely on start up.
That reminds me of a related point: The number of TCP frames can be considered more important than the number of bytes-per-frame when it comes to network performance. Most message exchanges, whether over WebSocket or HTTP, will occupy a comparable number of TCP frames, even if HTTP uses more bytes for the headers.
We also support long polling etc. but websocket servers are idling while our polling/push servers are at higher cpu utilization with comparatively lower loads.
...but I don't remember the advantages anymore :)
- Automatic reconnection
- Event ids
- Straightforward protocol built on plain old HTTP
[0] http://www.html5rocks.com/en/tutorials/eventsource/basics/
Yes, there are other ways to accomplish this, but why would you choose a kludgey way like long polling when an elegant solution is available? It makes no sense to me.
You also have to take into consideration different network issues, for instance last year Verizon 3G blocked WebSockets without any documentation. Or fragile wireless networks where the socket will break.
WebSockets definitely complicate the code, since you now have to deal with the connection before you can send a request. Keeping it constrained to realtime events cleaned things up nicely.
I was also trying to build some persistence into replaying chat messages on reconnection (data sync), but it was way easier to just turn "get_last_messages" into an endpoint that gets called on page load, or on socket reconnection.
My company's application has some real-time components and we've just been using pusher to handle it because it's simple and cheap. Is fanout something I should consider instead?
If you're not making an API, and you're just pushing data to your own client applications that you control, then Pusher and Fanout are more or less the same. Although you might like Fanout's simpler pricing model and our more open philosophy.
I'm going to bookmark this.
Why racer-browserchanel uses long pooling and not web sockets?
Web sockets does not guarantee order of messages between client and server, which is critical for OT.
[0] https://github.com/derbyparty/derby-docs/blob/master/faq.md#...https://github.com/sockjs/sockjs-client
(no affiliation, I just like it)
if (some event occurred){ do something over and over every so often that requires multitudes of processes including authentication, DNS etc. across many machines, that might not even ever return any value to the user. }
is not as nice as,
on('the arrival of a message', doSomething)
edit: pardon the sloppy pseudo syntax...
UDP would evince the same problem when traversing NAT, since it also would require state to be kept in middle-boxes. The only difference is that instead of periodically reconnecting, you'd need to periodically ping.
var source = new EventSource('/some/url/path');
source.onmessage = doSomething;
[0] http://dev.w3.org/html5/eventsource/Using long-polling, etc. this just doesn't seem feasible. I'm sure my HTTP stack _could_ push small messages in <17msec fairly reliably... but that's not what it's built to do.
Tossing the request all the way down my HTTP stack just seems wasteful. There might be middleware hitting persistent caches, there might be a reverse proxy out in front, etc. -- This all takes non-negligible resources away from other requests, and this all takes time.
---
I should note that I do use SSE or long polling for things like event notifications. So in the end I fully agree with the article. WebSockets are not a tool that should be applied haphazardly. In my stack WebSocket upgrade requests hit an entirely different server, so I take great care in electing where to use them.
Side note: Thinking about switching to SockJS since I use 1% of Socket.io features, but it's working well as is
We have a small abstraction over the browser WebSocket object that gives auto-reconnect (and catches disconnects through polling frames) and an interface that looks more like a Node.js EventEmitter. We fall back to (normal) polling if the socket takes more than a few seconds to connect.
Maybe we just change the user to long poll after a couple disconnects?
Maybe such best practices could also include some kind of poll/ping interval that adjusts based on the apparent stability of the link. Stable or wired connections could have very large intervals.
You start with a longpoll and get some data, then negotiate websockets (hey, my network and browsers are websockets capable!). Then the connection drops. And then you go through another round of everything again when you get back online (http + longpoll + websockets, instead of just http + longpoll).
Odds are, your website doesn't need websockets anyway, and 99% of your users are just fine with waiting a couple of seconds more to get their notification (and in the process, people with unreliable connections can still use your site).
Of course, if you're doing online stock trading notifications or something like that, you might actually need these two seconds. But then I'll strongly question your choice of using a browser for that :)
EDIT: fixed stray "*"
Odds are your website doesn't need CSS, but it certainly can benefit from it! I don't disagree that almost all websites could get by just fine without websockets, but that seems like an incredibly anti-innovative approach to web development to me. Instead we should focus on making the experience better, as opposed to just avoiding innovation altogether.
> 99% of your users are just fine with waiting a couple of seconds
Pretty much every study done in the last few years has suggested that is completely false, that as wait times rise above a second, the number of visitors who simply close out rises exponentially.
Sure, I can't think of all applications that would benefit from websockets, but so far, none of the ones I've seen do. I'm certain you can find at least a few exceptions, but my point is that it is only this: exceptions.