8

I am creating a server to monitor the online presence of clients on a webpage.

  • There will be 80-100 000 (eighty thousand) simultaneous clients to monitor.
  • I’m using .Net to write this.

Clients will contact a (separate) server using JavaScript (on the HTML-page) to tell the server that they are alive/online.

I’m considering one of two approaches:

  1. Persistent connections with keep-alive sent regularly. This will give me much higher precision on when clients disconnect and I don’t need to update memory structure (onlineinfo) too often because we know when client comes and goes. Additional benefits to network equipment / bandwidth.

  2. Clients (re)connect at intervals to tell server they are alive. This requires a lot of connections and will necessarily decrease the accuracy. I imagine intervals like 2-3 minutes is the best we can do. 80k/120=660 connections per second… ASP.Net don’t execute too fast so I’m unsure about this. 8 core system = ~10 ms per execution.

With this many connections there are obviously some limitations. I can’t spawn that many threads simultaneously for instance. 1 request to IIS spawning an ASP.Net application will use 1 thread until request is done.

Is the best option to write a stand-alone http-server? Doesn’t .Nets TcpListener leverage httpd.sys (IIS)?

Any (constructive) thoughts on the subject would be appreciated.

Edit: Adding some useful links to this post found by following links from Nicolas Repiquets answer:

Community
  • 1
  • 1
Tedd Hansen
  • 12,074
  • 14
  • 61
  • 97
  • 7
    Justa thought - Have you considered a load balancing strategy for this with multiple servers? – byte Nov 10 '10 at 14:22
  • As long as the clients don't require much processing for each keep-alive "request", I see no reason you shouldn't be able to do this. – Gabe Nov 10 '10 at 15:12
  • Interesting problem! The only thing that I could advise you is that you are playing with .NET and TCP/IP limits. Whatever solution you implement, think at first how to Scale Out. (divide the load into multiple servers) – Gerardo Grignoli Nov 10 '10 at 15:12
  • 1
    Is your client .NET based or just a web browser? If it is an application i would recommend you to send UDP packets instead of TCP connections... – Gerardo Grignoli Nov 10 '10 at 15:14
  • Sadly its a web browser so UDP will be difficult. Silverlight and possibly Flash could do this, but the computers accessing it are sort of restricted so there is no guarantee they can run these. – Tedd Hansen Nov 11 '10 at 08:55
  • Dividing load on multiple servers could be done, but this service is not *that* important. Running the servers are quite expensive. We could always just decrease update interval to 5 minutes, but id like to see if this is possible first. – Tedd Hansen Nov 11 '10 at 09:01

2 Answers2

4

100 000 persistent connections is not a viable option.

Sending HTTP requests at interval is way more feasible, and writing a dedicated HTTP server is an interesting choice IMO.

Take a look at this question for some orientations.

Community
  • 1
  • 1
Nicolas Repiquet
  • 9,097
  • 2
  • 31
  • 53
  • Why is it not a viable option? Windows supports this many connections as long as it isn't to/from the same IP pairs, in which case the 65k limit applies. – Tedd Hansen Nov 10 '10 at 14:46
  • 1
    You gonna run out of memory far before you run out of free port. Try to _gestimate_ the memory footprint of a single connection and multiply by 100000... – Nicolas Repiquet Nov 10 '10 at 15:08
  • 1
    Nicolas: Assuming that each connection requires 1k of data and you have 100,000 connections, the total usage will be 100,000k or 100M. It's been over a decade since I had a server that didn't have 100M of memory in it. – Gabe Nov 10 '10 at 15:14
  • 1
    1k of data? The socket alone allocate receive and send buffers of 8 to 16kb each. IIS probably allocates buffers too in order to queue async sends/receives. Add to that hundreds of objects associated to a HTTP connection and we are closer to 100kb than 1. – Nicolas Repiquet Nov 10 '10 at 15:42
  • The memory footprint of what I'm storing has been tested to around 4,5 MB for all connections. – Tedd Hansen Nov 11 '10 at 08:53
  • Send/receive buffers are allocated per socket when required (during the send/receive operation), each socket (iirc) takes 1k OS memory -- inputs on this would be nice though. :) – Tedd Hansen Nov 11 '10 at 08:54
  • Setting this as an answer since you'd be pretty insane to attempt this. :) – Tedd Hansen Dec 29 '10 at 09:45
0

I know you specifically say .NET, but you should probably take a look at NodeJS, as it does exactly what you're trying to do, but it is server-side JavaScript.

Tim P.
  • 2,903
  • 24
  • 26