Yes, if you'd like to implement serverless arhcitecture you should use Azure Functions for that. The typical serverless architecture is going to look like this

The client (i.e. browser) sends a negotiation request to an azure function, the response continas all information required to establish connection with Azure SignalR
. You should attach JWT token to a negotiation request. How you obtain a JWT token is up to you. Attaching it is pretty simple just provide a token factory when you create a signalR connection
const connection = new signalR.HubConnectionBuilder()
.withUrl('link to your azure functions api', {
accessTokenFactory: () => {
return 'your token'
}
})
.build();
For this to work you also need to set up an upstream connection so that your Azure SignalR
service can forward all events to your Azure Function. Azure funciton handles upstreamed events and sends requests to an Azure SignalR
to broadcast data to given user or multiple users.

The code for the SendMessage
method in a hub
is very similar to regular hubs except for Azure funciton bindings. You'll also need to extend ServerlessHub
class instead of Hub
and to install Microsoft.Azure.WebJobs.Extensions.SignalRService
package
public class ChatHub : ServerlessHub
{
[FunctionName(nameof(SendToUser))]
public async Task SendToUser([SignalRTrigger] InvocationContext invocationContext, string userName, string message)
{
await Clients.User(userName).SendAsync("new_message", new NewMessage(invocationContext, message));
}
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req)
{
var claims = GetClaims(req.Headers["Authorization"]);
var userName = claims.First(x => x.Type == ClaimTypes.NameIdentifier);
return Negotiate(userName.Value, claims);
}
private class NewMessage
{
public string ConnectionId { get; }
public string Sender { get; }
public string Text { get; }
public NewMessage(InvocationContext invocationContext, string message)
{
Sender = string.IsNullOrEmpty(invocationContext.UserId) ? string.Empty : invocationContext.UserId;
ConnectionId = invocationContext.ConnectionId;
Text = message;
}
}
}
You can also find a code sample with step by step instructions here
Edit:
If you don't want to go completely serverless and want to use regular web app it's also perfectly fine. The architecture diagram would look like this

And you should use regular hub class in this case. The code you posted should work just fine.
The connection management is done completely by Azure Signalr service, you don't need to do any additional synchronization and you don't need to store connection data in a database. Just set up the tier size and the number of units.
Here's the short description of how it works:
- Client (e.g. Js client in browser) sends request to a web app to a
negotiate
endpoint and receives link to azure signalr service and an access token. This is a JWT token. A JWT token consists of several parts. The second part of that token is the payload, which contains the claims.
- Using the data fetched from
negotiate
endpoint client connects to azure signalr service.
So the Azure SignalR service uses this access token, it receives from negotiate endpoint, to authenticate a user. You don't have to write any additional code for that it's all done under the hood by the library.
In case you use a web app, the negotiate
request is handled by the SignalR Sdk, you don't need to write any addional code for that.
It's all described in this article
And you can find detailed guide about implementing authentication here