Search code examples
javascriptc#signalrsignalr-hub

SignalR pass IProgress<T> from js client to hub


Is it possible to pass IProgress<T> from js client to the C# SignalR hub? What I'm trying to do is:

On the hub side:

public class ProgressHub : Hub<IProgressHub>
{
    public async Task Foo(string jobId, IProgress<int> progress)
    {
        Console.WriteLine($"Started monitoring {jobId}");

        for (int i = 0; i < 100; i++)
        {
            await Task.Delay(TimeSpan.FromSeconds(1)); // Simulate some work
            progress.Report(i);            
        }        
    }
}

public interface IProgressHub
{
    Task Foo(string jobId, Progress<int> progress);
}

On the js side:

connection
    .invoke("Foo", "this-is-job-id", progressPercentage => console.log(`Processed ${value}%`))
    .then(() => console.log("Processing done"));

The method on signalr hub gets called, but IProgress always ends up being null.


Solution

  • I just found out answer in Differences between ASP.NET SignalR and ASP.NET Core SignalR

    The ability to pass arbitrary state between clients and the hub (often called HubState) has been removed, as well as support for progress messages. There is no counterpart of hub proxies at the moment.

    Finally I've decided to do the following:

    On the hub side: RegisterToProgress([...]) which will internally call SendProgress([...]) that will send messages to client.

    On the js client side: call RegisterToProgress and listen to SendProgress messages.