23

I'm trying to understand how to best design an IIS/ASP.NET based websocket application, specifically regarding concurrency limitations.

I've read all the literature on IIS/ASP.NET regarding "concurrent Websocket connections" and how to tweak the various values - however, when speaking about websockets, what is the definition of "concurrent"? If I have opened a websocket and its sitting idle, is that "using" a connection? Do idle websockets count towards connection usage totals, or does it only count when a message is being sent/received?

I expect to have a very high (100s of thousands) number of websockets open at any one time, however there will be very few messages sent, perhaps a few per minute and they will always be server->client (and to a single, specific client, not a broadcast). Does/should this arrangement lead me down any particular implementation route?

It seems SignalR hubs are probably overkill, I don't need fallbacks for clients that dont support websockets and I only need to maintain a handle on the each clients connection, such that when my system "decides" to send a message to a particular client, it can route it appropriately.

Docs I'm referencing:

Thanks

Andrew Bullock
  • 36,616
  • 34
  • 155
  • 231

1 Answers1

15

however, when speaking about websockets, what is the definition of "concurrent"? If I have opened a websocket and its sitting idle, is that "using" a connection? Do idle websockets count towards connection usage totals, or does it only count when a message is being sent/received?

Right, a open connection sitting idle does not consume much resources beyond TCP keep-alives and maybe protocol and/or application level ping/pongs if your server supports them. More importantly, as Websockets are connection oriented you may be holding some state associated with the connection as well (an user object, user data, etc...)

I expect to have a very high (100s of thousands) number of websockets open at any one time, however there will be very few messages sent, perhaps a few per minute and they will always be server->client (and to a single, specific client, not a broadcast). Does/should this arrangement lead me down any particular implementation route?

Yes, to the route of not using SignalR: SignalR Scale-out (check the limitations section). Use WebSockets directly and implement your own messaging back-end with a framework that allows smart routing like RabbitMQ for example. You don´t want to use a backplane that is basically doing "fan-out" to all nodes, especially if the data is per user.

SignalR is a polyfill, a transient framework until the day WebSockets are broadly supported... and that already happened. Also forgot to mention that WebSockets are available from Windows server 2012 onwards :)

Jacob
  • 3,598
  • 4
  • 35
  • 56
vtortola
  • 34,709
  • 29
  • 161
  • 263
  • Thanks for your response. So youre saying that due to my low message throughput, I shouldnt really need to care about "concurrency"? Do you know what limitations I might hit, or what theyre called and so where to read about them? – Andrew Bullock Jul 28 '15 at 19:44
  • Oh no, due the fact that you are not broadcasting but sending highly segmented messages (not broadcast, not by group, but by user) you should not use SignalR. SignalR uses a backplane for scaling out, meaning that if you have 8 servers, a message is sent to the 8 servers independently of where you user is connected. It may not be a big issue right now with a low message frequency, but it may be a big shot in the foot if your application tries to get bigger :) If you plan to support hundreds of thousands of concurrent connections, scaling out appropriately must be a very big item in your list. – vtortola Jul 28 '15 at 19:47
  • Sorry, I think we've got crossed wires. I understand backplaning. The first part of your answer that addressed the first part of my question seemed to suggest you were downplaying the concern of connection concurrency in a low message frequency, high client situation. How can I predict the number of clients I can support per server? – Andrew Bullock Jul 28 '15 at 19:57
  • 1
    Would recommend writing some test code to automate large numbers of clients if you are not sure. I've used web sockets in a production environment but with <100 clients, albeit with more messages, up to around 50 per minute. – Adam Marshall Jul 28 '15 at 20:02
  • 1
    Well that prediction is a little bit difficult to do and varies on what you understand as "few per minute" and the average message size. I would start to benchmark early. Obviously with 100s of thousands you need to ... at least... plan for it :) A WebSocket is just a transport, so big part of how your solution perform and scales will be in how you handle threading and how you deliver messages to the websocket connections. For example, if you open a new Thread per connection, do not expect "thousands" of them. – vtortola Jul 28 '15 at 20:06
  • 3
    Calling SignalR a "polyfill" is wrong. SignalR uses websockets most of the time, and is mainly intended to provide a level of abstraction to websockets and simplify their usage. It's still recommended today by Microsoft Docs and is not marked as obsolete in any way. – Jez Feb 15 '23 at 12:20