1

Scenario;

We currently have a WebApp acting as an API for an Angular client app and we have a separate azure functions project where we handle messages queued on the service bus. We have quite a lot of async functionality where a user triggers an action on the client, handled by the api which in turn queues some messages on the message bus. These are then handled by the functions project.

Now we're trying to add "live updates" in the client app.

The triggers from these live updates may both come from messages being handled, or other endpoints on the api being called. But I'm struggling.

Using the code samples from Microsoft I've managed to setup the "chat application" inside my api with a Hub to receive and broadcast messages to the chat client app. But I'm struggling to connect my Azure Function to the same signalr service so it can also broadcast messages to the chat.

WebApp setup:

Added following lines of code in the correct place in Startup.cs

services
    .AddSignalR()
    .AddAzureSignalR(configuration.GetConnectionString("SignalR"));

app.MapEndpoints(endpoints => {
    endpoints.MapHub<ChatHub>("/chat");
});

Created a Hub: ChatHub.cs

public class ChatHub : Hub
{
    public async Task BroadcastMessage(string name, string message)
    {
        await Clients.All.SendAsync("broadcastMessage", name, message);
    }

    public async Task Echo(string name, string message)
    {
        await Clients.Client(Context.ConnectionId)
                .SendAsync("echo", name, $"{message} (echo from server)");
    }
}

So far so good, the client app can connect and as a user I can both broadcast messages as well as echo messages back to myself.

I created an endpoint on one of the controllers to be able to test if I can send messages to the chat from within a controller:

[HttpPost("chat/message")]
public async Task<ActionResult> HandlePostChatMessage(string message)
{
    await _chatUtil.SendChatMessage("ApiTrigger", message);

    return NoContent();
}

This also works as expected: clientapp

Now I created a timertrigger in the function project, that should also send messages every 30 seconds (as a test to see if everything works)

SendChatMessageTimerTrigger.cs

public class SendChatMessageTimerTrigger
{
    [FunctionName(nameof(SendChatMessageTimerTrigger))]
    public async Task Run(
        [TimerTrigger("%Functions:" + nameof(SendChatMessageTimerTrigger) + ":TriggerSchedule%")] TimerInfo timerInfo,
        [SignalR(ConnectionStringSetting = "ConnectionStrings:SignalR", HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages)
    {
        await signalRMessages.AddAsync(
            new SignalRMessage
            {
                Target = "broadcastMessage",
                Arguments = new[] { "FunctionTrigger", $"Current time: {DateTimeOffset.UtcNow}" }
            });
    }
}

From what I can see debugging the function, SignalR is connected (so the connectionstring is found). No exceptions are being thrown when the method executes. But, these messages are not being show in the client app.

Does anyone have any insights as to why the functions app isn't able to successfully send chat messages? Or am I missing something else?

Jason Pan
  • 15,263
  • 1
  • 14
  • 29
Nimesco
  • 688
  • 4
  • 13
  • I'm not really sure what you mean. Basically a user's data might have changed after a message was processed by the function and I want to notify the client that the data has changed. Webhooks would be between 2 servers. And I'm trying to nofity the client app the users data has changed. – Nimesco Aug 09 '23 at 09:58
  • I have updated the answer with the workflow, hope it can help you. And I still think the signalr trigger should be the best way to implement it. – Jason Pan Aug 15 '23 at 05:15

1 Answers1

0

Update

This is the ASRS workflow, as I know your azure function also should be a client to connect ASRS.

enter image description here

===============================================================

Yes, we should add upstream url in azure portal.

enter image description here

In your development, you can use ngrok to expose the Function_App_URL. and the key we can leave it blank. But If you want to use in production environment, you need to use API_KEY.

All the detailed steps, you can find here.

SignalR Service trigger binding for Azure Functions

Jason Pan
  • 15,263
  • 1
  • 14
  • 29
  • This is the other way around. I don't want SignalR to trigger my function, I want function to send a message through SignalR to the client. – Nimesco Aug 09 '23 at 09:58
  • Hi @Nimesco, Ok, you should use C# SDK to create a HubConnection as client, and try to connect the webapplication, then we can broadcast message successfully. – Jason Pan Aug 09 '23 at 10:02