Local development with Azure SignalR Service and Azure Functions
Asked Answered
R

2

6

I'm using Azure SignalR Services, which is running in the cloud, and running an Azure Function App, which runs locally on my laptop on localhost. I have the following hub:

public class LeaderboardHub : ServerlessHub
{
    [FunctionName("negotiate")]
    public async Task<SignalRConnectionInfo> Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req) =>
        Negotiate(req.Headers["x-ms-signalr-user-id"]);

    [FunctionName(nameof(OnConnected))]
    public async Task OnConnected([SignalRTrigger]InvocationContext invocationContext, ILogger logger)
    {
        logger.LogInformation($"{invocationContext.ConnectionId} has connected");
    }
}

I connect to my hub like so:

 const apiBaseUrl = window.location.origin;
 const connection = new signalR.HubConnectionBuilder()
     .withUrl(apiBaseUrl + '/api')
     .configureLogging(signalR.LogLevel.Information)
     .build();

 connection.start()
     .catch(console.error);

When I run this, I can set a breakpoint at Negotiate() and see the connection made. When I send messages to my hub, they show up on the client. However, I never see the OnConnected method get called. Likewise, if I create new SignalRTrigger methods and call them in Javascript, they never get called.

My Theory: I'm hoping I'm wrong, but I'm somewhat guessing this is because I'm running my app on my own laptop under localhost, and Azure SignalR Services has no way to "forward" the message on to me, since Azure can't connect to my laptop. I haven't tried deploying my Function App to Azure to run it there, but I'm guessing if I ran it within Azure, there would be a two-way connection.

  1. Is this a correct assumption? Meaning, is this a limitation of Azure SignalR Services?
  2. Is there any way around this? For example, running some local AzureR SignalR proxy service or emulator? How do people usually do development with SignalR without deploying every little change to Azure?

Thanks!

Resent answered 7/10, 2022 at 3:13 Comment(0)
R
5

Figured out my own question! First off, I was right. Second, there is a very cool SignalR local emulator that can be found here:

https://github.com/Azure/azure-signalr/blob/dev/docs/emulator.md

After installing and running this, my code worked perfectly as expected.

Resent answered 7/10, 2022 at 3:23 Comment(0)
J
-1

To invoke and debug a SignalR-triggered function in your Azure Functions App locally, you need to configure two key aspects:

  1. Expose the local Azure Function to the Internet: To make your local Azure Function accessible from the internet, you can use a tool like Ngrok. This application allows you to create a tunnel between your local server (where your Azure Function is running) and a public URL. This way, any request sent to the public URL will be forwarded to your local environment, allowing you to test and debug your function in a near-production environment.

  2. Configure the "Upstream Endpoint" in Azure SignalR: Once your Azure Function is accessible via the tunnel, you need to configure the Upstream Endpoint in the Azure SignalR service. You can do this from the Azure portal by providing the URL of the tunnel generated by Ngrok. This configuration will allow Azure SignalR to send messages or events to your local Azure Function through the tunnel connection.

    • For Production: When connecting Azure SignalR to your production Azure Function, you need to include the API Key in the upstream endpoint. The endpoint should follow the format: https://<Function_App_URL>/runtime/webhooks/signalr?code=<API_KEY>. The <API_KEY> can be retrieved from your Azure Function keys, and the recommended key for this scenario is the one named "signalr_extension". This key should be used to complete the upstream endpoint URL. You can find this API Key in the Azure portal under the Azure Function's "Functions -> Application keys" section.

    • For Local Development: While testing locally, there’s no need to include the API Key in the upstream endpoint. Instead, the upstream endpoint should be configured using the Ngrok URL like this: <Ngrok_URL>/runtime/webhooks/signalr. This allows Azure SignalR to communicate with your locally hosted Azure Function through the Ngrok tunnel without requiring the production API Key.

You can find documentation about configuring "Upstream endpoints" in Azure SignalR at Upstream endpoints in Azure SignalR Service and Azure Function and Azure SignalR serverless mode integration.


Additional Tip: Make sure to keep Ngrok running during the testing and debugging process, as the tunnel URL will become unavailable if Ngrok is stopped.

This way you don't need to install any emulator, you just need to perform a "forwarding" between the public URL provided by Ngrok and the local server where you host the Azure Function (localhost:port).

To see more documentation about Azure SignalR serverless mode you can see the following links:


Jena answered 18/10, 2024 at 15:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.