Reputation: 193
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"
}
]
]
}
Upvotes: 7
Views: 6111
Reputation: 61
For those still finding this issue, I was using Blazor server & I had a very similar problem, however for me, the issue was because I did not have empty constructors on the objects I was sending back. Don't make the same silly mistake I made!
I had something similar to the below, however my RoomDTO
object did not have a empty constructor.
hub.cs
List<RoomDTO> rooms = await _chatService.GetAllRoomsAsync();
await Clients.Caller.SendAsync("PushRoomsList", rooms);
component.cs
hubConnection?.On<List<RoomDTO>>("PushRoomsList", HandleRoomsList);
Upvotes: 1
Reputation: 193
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.
Upvotes: 9