0

I need to send SignalR message to the specific user id not all the clients who connected to the Azure SignalR service in Serverless mode. Below is the code where I want to set user id.

```
 [FunctionName("ProcessUpdate")]
 public static void Test([ServiceBusTrigger(topicName: "test", subscriptionName: "test", Connection = "AzureServiceBusConnectionString")] ServiceBusReceivedMessage  message,
         [SignalR(HubName = "Notification")] IAsyncCollector<SignalRMessage> signalrMessageCollector, ILogger logger)
        {           
            var signalrMessage = new SignalRMessage()
            {
               UserId = //assign authenticated user id
                Target = "receiveUpdate",
                Arguments = new[] { message.Body.ToString() }
            };
            signalrMessageCollector.AddAsync(signalrMessage);            
        }
```

I checked the documentation here

https://learn.microsoft.com/en-us/azure/azure-signalr/signalr-concept-serverless-development-config

It does not say how to access the user Id from Negotiate function in other azure functions that are event handlers for sending SignalR messages to clients.

I tried to use SignalRConnectionDetail sdk code in the output binding.Its not working mostly it seems that its part of the input binding.

Chays
  • 1
  • 2
  • Do you want to send the message to the User but not on a specific connection? Remember that each tab connected to SignalR is a unique connection. Sending a message to a user and not a connection means the message will be received by all open connections of the User. – Raffy Sep 10 '22 at 01:46
  • I want to send based on User Id and I think all the connections mapped to that user would receive the message. Its fine for my use case if I receive it like this. But I am also keen to know how can I do it based on the connection id. – Chays Sep 10 '22 at 13:52

1 Answers1

0

App Service authentication sets HTTP headers named x-ms-client-principal-id and x-ms-client-principal-name that contain the authenticated user's client principal ID and name:

[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
    [HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req, 
    [SignalRConnectionInfo
        (HubName = "chat", UserId = "{headers.x-ms-client-principal-id}")]
        SignalRConnectionInfo connectionInfo)
{
    // connectionInfo contains an access key token with a name identifier claim set to the authenticated user
    return connectionInfo;
}

You can access them like this in the trigger above:

var id=req.Headers["x-ms-client-principal-name"].ToString();

SignalR Service input binding for Azure Functions

Mo Nazemi
  • 2,618
  • 2
  • 16
  • 23
  • My questions is regarding accessing the user id in other than the negotiate functions like in the event handlers where I want to send user id in sending message or so. I want the user id to be able to access in azure signalr output binding like I mentioned in my sample code [FunctionName("ProcessUpdate")]. is there a way I can access the access token/user id here [FunctionName("ProcessUpdate")], not in negotiate function. – Chays Sep 12 '22 at 06:49
  • Your `ProcessUpdate` is a service bus trigger. I assume you push a message to the service bus somewhere. That is where you need to add the user id to that service bus message as a custom property which then you can access in the trigger – Mo Nazemi Sep 12 '22 at 11:23
  • yes we can do that. but I want to access the authentication id from the access token (generated in negotiate function). – Chays Sep 12 '22 at 14:48
  • I am quite confused by your query, to be honest. Can you elaborate on your use case ?? The point is that you need to somehow get that user id to your trigger. Given that `ProcessUpdate` is a service bus trigger, the logical approach is to store it in a service bus message, so that it can be accessed there. – Mo Nazemi Sep 12 '22 at 14:55
  • I just want to know if its possible to get the user id with any of the inhouse bindings, code of Azure Signalr service in serverless mode. since when client app first has to invoke negotiate function, it could pass a JWT or identity token that can have claims related to user information who logged on. the negotiate function's reply would populate the signalr access token with the same claims that are passed to it. This access token would further gets used to connect to Azure signalr service event handlers. so if its possible to access this token, then we can have the userid right? – Chays Sep 12 '22 at 16:14