I have an EventGrid
Trigger Azure Function
(using the isolated worker on .net7
) that is called each time a client connects a SignalR hub. It is setup like this:
[Function("v1-on-connectivity-events-changed")]
public async Task OnConnectivityEventsChangedAsync
(
[EventGridTrigger]
EventGridConnectivityEvent eventGridConnectivityEvent,
FunctionContext functionContext
)
{
_logger.LogWarning("Event grid trigger received. Data='{ConnectionInfo}'", JsonSerializer.Serialize(eventGridConnectivityEvent));
...
}
On the client side, the application connects the SignalR via the Negotiate API like this:
_hubConnection = new HubConnectionBuilder()
.WithUrl(hubEndpoint.AbsoluteUri, options =>
{
// Adds the application token to the options' header.
options.AccessTokenProvider = () => Task.FromResult(user.IdentityToken.AccessToken)!;
options.Headers.Add("userSid", user.IdentityToken.UserSid);
})
.Build();
...
await _hubConnection.StartAsync();
Here is what the Negotiate
function is doing which returns the URL along with an additional :
[Function("negotiate")]
public Task<SignalRConnectionInfo> OnNegotiateAsync
(
[HttpTrigger(AuthorizationLevel.Anonymous, "POST")]
HttpRequestData httpRequestData,
[SignalRConnectionInfoInput
(
HubName = Constants.HubName,
ConnectionStringSetting = "AzureSignalRConnectionString"
)]
SignalRConnectionInfo signalRConnectionInfo
)
{
return ExecuteAsync(httpRequestData, async claimsPrincipal =>
{
IUserPrincipal userPrincipal = await RetrieveClaimsAsync(httpRequestData, claimsPrincipal);
signalRConnectionInfo.Url += $"&userSid={userPrincipal.UserSid}";
return signalRConnectionInfo;
});
}
The OnConnectivityEventsChangedAsync
Function is properly called when the client gets connected. However, it does not provide all the information that I need: the User ID
is missing.
Question
In the SignalR documentation, it is stated that the connected event should provide the user ID
along with the connection ID
. Here is what I get:
{
"Id":"56f3ab25-11d7-41d6-acbb-8429a741d746",
"Topic":"/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.SignalRService/SignalR/<signalr_instance>",
"Subject":"hub/updates",
"EventType":"Microsoft.SignalRService.ClientConnectionConnected",
"EventTime":"2022-11-27T19:22:19.2349923Z",
"Data": {
"timestamp":"2022-11-27T19:22:19.2349923Z",
"hubName":"updates",
"connectionId":"gmJM_GHVkXsQuS5C1LhdXXXXX"
}
}
What should I do to get the User ID
along with the Connection ID
?
I have to set the UserId
property of the SignalRConnectionInfoInputAttribute
to indicate how to get the user ID. In my case, since the user ID is in the header of the HTTP request as userSid
, I must do the following:
[Function("negotiate")]
public Task<SignalRConnectionInfo> OnNegotiateAsync
(
[HttpTrigger(AuthorizationLevel.Anonymous, "POST")]
HttpRequestData httpRequestData,
[SignalRConnectionInfoInput
(
HubName = Constants.HubName,
ConnectionStringSetting = "AzureSignalRConnectionString",
UserId = "{headers.userSid}"
)]
SignalRConnectionInfo signalRConnectionInfo
)
{
...
return signalRConnectionInfo;
}