3 ms·
Yep. We initially went with a 1 hour timeout — worst case, the client drops every hour, and then immediately reconnects. We actually moved to a heartbeat system
by atto 13y ago
Yep. We initially went with a 1 hour timeout — worst case, the client drops every hour, and then immediately reconnects. We actually moved to a heartbeat system recently, because we found issues with spotty connections where we'd have packets lost / delayed (for up to a couple minutes), but the server and client both believed they were connected.
Scaling the heartbeat is actually not a big issue. If you're actively using the socket for things, the overhead of that is likely much higher than supporting pings. You'll actually hit port limitations first (if you can support ~65k connected clients per machine), in our experience. 3000 pings a second isn't too bad (that's 100k clients, pinging every 30 seconds or so). You can also change how fast the client is pinging based on client activity.
- derefr 13y ago> You'll actually hit port limitations first (if you can support ~65k connected clients per machine) This isn't actually a limit, by the way. The port limitation is a uniqueness constraint on full (source IP, source port, dest IP, dest port) tuples; it just means one client can't have more than 65k connections open to your server (which tends to trip people up, because they see themselves running into the limit when benchmarking parallelism--because they're sending all the requests from their own computer.) What you'll usually hit first is the open file descriptor ulimit.
- atto 13y agoAh cool. Yep, that's what we did, thanks. edit: I thought too fast. Amfy's reply to you is correct (and what I have seen previously). When proxying with nginx, you use up the ports locally (unless I'm missing something?).
- derefr 13y agoAh, I got confused with what exactly you meant. This is indeed an actual problem, but it's one with an easy solution: you just make each backend process listen on multiple ports, and list them all as separate entries in the nginx's upstream{} section for that backend. One backend with 1024 ports open = 67M connections nginx can make to that backend. Again, you're not "using up" local ports, just (IP/port, IP/port) pairs--so increasing the number of remote ports you want to talk to allows you to make more connections just as well as if you could increase the number of local ports used to talk to them. (This might not be so simple for some servers which expect to only listen on one port; the workaround is to use multiple IPs for the backend server, and make sure the backend process is listening on 0.0.0.0. They don't have to be real IPs--you can just as well do port-forwarding on the backend box from one-IP:lots-of-ports to lots-of-virtual-IPs:one-port. It's simple enough to listen on multiple ports in both Node and Erlang, though, so this probably doesn't matter for most people writing websocket servers.)
- Amfy 13y agoYou can increase the open file descriptor ulimit very easily. Regarding the port-limitation: I think he means the connections from nginx to your Websocket-App...
- deleted 13y ago[deleted]
- natejenkins 13y agoIs there a reason why a proper websocket connection along with the client pinging the server is preferable over long-polling?
- atto 13y agoYes, for a few reasons — most are application specific, though. An active websocket connection does have a faster response time than a regular HTTP connection ([1]). The difference here isn't a ton, but may affect real-time applications. The packets are also smaller, so less overhead if you're sending many. The biggest difference I saw is that when the client or server needs to send several quick requests (many within a couple second), long polling breaks down. From the spec ([2]), "Once the server sends a long poll response, typically the client immediately sends a new long poll request." This delay can add up, and is not pure full duplex. Chunked responses help for server -> client, but client -> server still has the same issues. [1] http://eng.42go.com/secure-websockets-vs-https-benchmark/ http://eng.42go.com/secure-websockets-vs-https-benchmark/ [2] http://tools.ietf.org/html/draft-loreto-http-bidirectional-07#section-2.1 http://tools.ietf.org/html/draft-loreto-http-bidirectional-0...
- natejenkins 13y agoAwesome stuff, thanks. Your second point could explain some of the mysterious non-updates that I've seen from time-to-time when using faye with long-polling behind nginx.
- daemon13 13y agoany pointers how you implemented hearbeat with nginx? thank you
- atto 13y agoYou actually need to implement it outside of nginx. The easiest way is just have the client send a message every x seconds, and your application server will immediately respond. If the server does not respond quickly (within a few seconds), close the connection and optionally reconnect.