6

I have a ASPNet.Core WebApi, with signalR. I have angular app, that consumes the webAPI, and I want to replace it with a Blazor Webassembly app. I have a problem with signalR in the Blazor app.

I create a hubconnection, set it up, and when the server sends data, the Hubconnection.On method is not invoked. Here's my code:

protected override async Task OnInitializedAsync()
{
    _hubConnection = new HubConnectionBuilder()
        .WithUrl("https://localhost:45299/hubs/accounthub", cfg =>
        {
            cfg.SkipNegotiation = true;
            cfg.AccessTokenProvider = () => Task.FromResult(token);
            cfg.Transports = HttpTransportType.WebSockets;
        })
        .Build();

    _hubConnection.On<IEnumerable<AccountResponse>>("accountschanged", (accounts) =>
    {
        foreach(var account in accounts)
        {
            Console.WriteLine(account.Name);
        }
    });
    await _hubConnection.StartAsync();
}

In the network tab, I see that the connection is ok, I receive new data, but the method in hubconnection.On doesn't get fired. I double checked the method name, and it is the same. In the angular app it works fine and as data gets send from the server, I don't there's any problem with the server code.

I use Fluxor for state management, and I fire an action in the 'On' method, I just replaced is with a single Console.WriteLine for simplicity.

Edit: Added server code, and the message received Here's the server code, 'AccountsChanged' is called when an account is changed:

public class AccountHub : Hub, IAccountHub
{
    private readonly IHubContext<AccountHub> _accHub;
    private readonly IAggregateMapper _mapper;

    public AccountHub(IHubContext<AccountHub> accHub, IAggregateMapper mapper)
    {
        _accHub = accHub;
        _mapper = mapper;
    }

    public async Task AccountsChanged(Guid userId, IEnumerable<Account> accounts)
    {
        var mapped = _mapper.MapAll<Account, AccountResponse>(accounts);
        await _accHub.Clients.User(userId.ToString()).SendAsync("accountschanged", mapped);
    }
}

And here's the message I receive (I make a request from Postman), copied from the network tab (I removed additional properties of accounts to keep it simple):

{
    "type":1,
    "target":"accountschanged",
    "arguments":[
        [
            {
                "id":1,
                "name":"bank account 1"
            },
            {
                "id":2,
                "name":"wallet 1"
            }
        ]
    ]
}
petyusa
  • 163
  • 2
  • 10
  • You're passing in a string with the value 'url' in the call to WithUrl – auburg Jul 13 '20 at 08:57
  • I'm passing the right url, just replaced it. I wouldn't get any messages if the url was wrong. I'll edit it the post not to confuse anyone. – petyusa Jul 13 '20 at 08:58
  • Can you include the code to whatever that's posting the message on the hub method – auburg Jul 13 '20 at 09:00
  • I added the server code, and the message I receive from the hub. – petyusa Jul 13 '20 at 09:17
  • Do you see any errors in the debug output window in Visual Studio when running your Blazor app ? – auburg Jul 13 '20 at 09:25
  • Also try adding async in your on handler: _hubConnection.On>("accountschanged", async (accounts) => – auburg Jul 13 '20 at 09:26
  • There's no error in output, or browser console. I tried adding asnyc, and await Task.CompletedTask at the end of the function, but nothing has changed. – petyusa Jul 13 '20 at 09:38

1 Answers1

8

I finally found the problem. It was about serializing the received json message. I had to add .AddJsonProtocol(), and set it up, here is the final code:

_hubConnection = new HubConnectionBuilder()
    .WithUrl("http://localhost:59225/hubs/accounthub", cfg =>
    {
        cfg.SkipNegotiation = true;
        cfg.Transports = HttpTransportType.WebSockets;
        cfg.AccessTokenProvider = () => Task.FromResult(token);
    })
    .AddJsonProtocol(cfg =>
    {
        var jsonOptions = new System.Text.Json.JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true,
        };
        jsonOptions.Converters.Add(new JsonStringEnumConverter());

        cfg.PayloadSerializerOptions = jsonOptions;
    })
    .Build();

I find it strange that I didn't get any error message btw.

petyusa
  • 163
  • 2
  • 10