I want to implement SignalR in C#/.net (3.1) for an Azure Function with an extended negotiate function, so that messages can be send to a specific user.
The basic negotiate for broadcasting is working.
[FunctionName("negotiate")]
public static SignalRConnectionInfo GetSignalRInfo(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
[SignalRConnectionInfo(HubName = "myHub")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
Now I wanted to use the extended Version from the MS documentation:
[FunctionName("negotiate")]
public static SignalRConnectionInfo GetSignalRInfo(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
[SignalRConnectionInfo(HubName = "myHub", 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;
}
This wont work, like discussed in this article: https://charliedigital.com/2019/09/02/azure-functions-signalr-and-authorization/
So I rewrite my negotiate function like this:
[FunctionName("negotiate")]
public static async Task<SignalRConnectionInfo> GetSignalRInfo(ILogger log,
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
IBinder binder)
{
string userId = req.Headers["x-user-id-header"]; // This value is here, but not available in the binding for the attribute
string signalREndpoint = Environment.GetEnvironmentVariable("SignalR_ENDPOINT", EnvironmentVariableTarget.Process);
log.LogInformation("Called negotiate with userID: " + userId + " and SignalR Endpoint: " + signalREndpoint);
SignalRConnectionInfoAttribute attribute = new SignalRConnectionInfoAttribute
{
ConnectionStringSetting = signalREndpoint,
HubName = "myHub",
UserId = userId
};
// This style is an example of imperative attribute binding; the mechanism for declarative binding described below does not work
// UserId = "{headers.x-my-custom-header}" https://docs.microsoft.com/en-us/azure/azure-signalr/signalr-concept-serverless-development-config
SignalRConnectionInfo connection = await binder.BindAsync<SignalRConnectionInfo>(attribute);
return connection;
}
But now I get the following error:
Executed 'negotiate' (Failed, Id=df9db581-2251-4fb1-b1b5-5f53b173533e, Duration=465ms) [2022-07-13T13:31:00.871Z] System.Private.CoreLib: Exception while executing function: negotiate. Microsoft.Azure.WebJobs.Extensions.SignalRService: The SignalR Service connection string or endpoints are not set.
The Endpoint is correctly read from the local.json and the name of the hub is also correct.
What am I missing here?