Should signalr server-side methods be async when calling Clients?

Daniel Marcotte picture Daniel Marcotte · Oct 5, 2013 · Viewed 9.3k times · Source

I'm following the "SignalR Tutorial" on : http://www.asp.net/signalr/overview/hubs-api/hubs-api-guide-server

So let's assume this simple Chat Method :

public void Send(string name, string message)
{
     // Call the addNewMessageToPage method to update clients.
     Clients.All.addNewMessageToPage(name, message);
}

Suppose that I have a Chat room with 50 000 users. Would there be any benefit of changing the Send method to be async, like this :

 public async Task Send(string name, string message)
 {
     // Call the addNewMessageToPage method to update clients.
     await Clients.All.addNewMessageToPage(name, message);
 }
  • Will IIS hold the current Request (of the user who published the chat) and wait until every clients are notified?
  • Is the call to "Client" totally asynchronous under the hood and the request is released at this point?

Thank you!

Answer

davidfowl picture davidfowl · Oct 5, 2013

The only reason you should await the task is when you're using scaleout. By default, the in memory message bus returns a completed task because the operation is so fast there's no point making it async but you can if you want to. To answer your questions:

  • We don't send to clients on the same call stack doing the method invocation (e.g. Clients.All.addNewMessage doesn't wait on anything except publishing to the message bus). No request thread will wait on clients to receive anything (we don't support waiting on the client getting the message in SignalR for normal invocations).

  • It is always async even if you don't use await at the call site. We have a message broker that actually does the writing to the clients. When you call that method, you're just putting a message in a buffer. At some time in the future, that message gets delivered to clients.

In the scaleout scenario, calling a client method sends a message to an external service (sql, redis, service bus) and that can fail so you want to await the task so that exceptions are observed.

Hope that helps