Search code examples
c#wpfazure-functions.net-6.0azure-signalr

Azure SignalRTrigger not working with Azure Functions


I have created an Azure SignalR Serverless service with Azure Functions. My client is a .NET 6 WPF Application.

The negotiate function is working as expected, and the connection gets established succesfully. The CosmosDBTrigger, HttpTrigger and TimerTrigger functions also work as expected. However, the SignalRTrigger isn't working and I can't figure out why.

SignalRTrigger function:

[FunctionName("SignalRTest")]
public async Task SignalRTest([SignalRTrigger("myHub", "messages", "SignalRTest")] InvocationContext invocationContext, string message, ILogger logger)
{
    logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
    await Clients.All.SendAsync("signalRTestMessage", message);
}

Client Configuration:

connection = new HubConnectionBuilder()
             .WithUrl("https://<SiteURL>.azurewebsites.net/api")
             .Build();
             
await connection.StartAsync().ContinueWith(async (e) =>
{
    try
    {
        await connection.InvokeAsync("SignalRTest", "TestMessage");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
});

The exception always returns the error message:

Invocation failed, status code 404

I have configured the SignalR Upstream with the signalr_extension key generated in Azure Functions.

I have followed the official documentation on Microsoft docs but still couldn't fix the issue.


Solution

  • I empathize with you since we've been struggling with sending messages as well even though so much documentation makes it appear trivial. One thought I had on your situation is: Should you use the URL from the negotiate response when creating a hubConnection?

    Here's our typescript example that uses a NegotiateResponse object with the URL and AccessToken returned from the negotiate HTTP call:

    this.signalRService.negotiate().subscribe({
      next: (negotiateResponse) => {
          let options = {
            accessTokenFactory: () => negotiateResponse.accessToken,
          };
    
      const connection = new signalR.HubConnectionBuilder()
          .withUrl(negotiateResponse.url, options)
          .build();
    

    P.S. As mentioned we are also struggling with message sending, so this may not be a solution for you although I hope it is.