Communication between a WebJob and SignalR Hub

2019-03-27 03:05发布

问题:

I have the following scenario:

  • I have an azure webjob (used to send mails) and I need to check the progress of the webjob in my web application.
  • I am using SignalR to communicate with clients from my server.
  • When I want to send an email, I push a message in the queue and the azure webjob does his job.

The question is, how can I communicate the progress of the webjob to the client? Originally my idea was to push a message from the webjob, so the Hub could read it from the queue. Then, I would notify clients from the hub. However, I am not able to find a way to communicate the webjob and the hub, I do not know how to trigger an action in the hub when a message is pushed into the queue or in the service bus. That is to say, I dont know how to subscribe the hub to a certain message of the queue.

Can someone help me with it?

回答1:

The way that I have done it is to set up the webjob as a SignalR client, push messages via SignalR from the webjob to the server, then relay those messages to the SignalR web clients.

Start by installing the SignalR web client (nuget package ID is Microsoft.AspNet.SignalR.Client) on your webjob.

Then in your webjob, initialise your SignalR connection hub and send messages to the server, e.g.:

public class Functions
{
    HubConnection _hub = new HubConnection("http://your.signalr.server");
    var _proxy = hub.CreateHubProxy("EmailHub");

    public async Task ProcessQueueMessageAsync([QueueTrigger("queue")] EmailDto message)
    {
        if (_hub.State == ConnectionState.Disconnected)
        {
            await _hub.Start();
        }

        ...

        await _proxy.Invoke("SendEmailProgress", message.Id, "complete");
    }
}

Your SignalR server will receive these messages and can then relay them to the other SignalR clients, e.g.:

public class EmailHub : Hub
{
    public void SendEmailProgress(int messageId, string status)
    {            
        Clients.All.broadcastEmailStatus(messageId, status);
    }        
}