SignalR C # Client Hubconnection.On не запущен

У меня есть ASPNet.Core WebApi с signalR. У меня есть приложение angular, которое использует webAPI, и я хочу заменить его приложением Blazor Webassembly. У меня проблема с signalR в приложении Blazor.

Я создаю хаб-соединение, настраиваю его, и когда сервер отправляет данные, метод Hubconnection.On не вызывается. Вот мой код:

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();
}

На вкладке сети я вижу, что соединение в порядке, я получаю новые данные, но метод в hubconnection.On не запускается. Я дважды проверил имя метода, и оно то же самое. В приложении angular он работает нормально, и когда данные отправляются с сервера, у меня нет проблем с серверным кодом.

Я использую Fluxor для управления состоянием и запускаю действие в методе «On», который я только что заменил на одну Console.WriteLine для простоты.

Изменить: добавлен код сервера и получено сообщение. Вот код сервера. AccountsChanged вызывается при изменении учетной записи:

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);
    }
}

И вот сообщение, которое я получаю (я делаю запрос от почтальона), скопированное с вкладки сети (для простоты я удалил дополнительные свойства учетных записей):

{
    "type":1,
    "target":"accountschanged",
    "arguments":[
        [
            {
                "id":1,
                "name":"bank account 1"
            },
            {
                "id":2,
                "name":"wallet 1"
            }
        ]
    ]
}

person petyusa    schedule 13.07.2020    source источник
comment
Вы передаете строку со значением url при вызове WithUrl   -  person auburg    schedule 13.07.2020
comment
Я передаю правильный URL, просто заменил его. Я бы не получил никаких сообщений, если бы URL был неправильным. Отредактирую пост, чтобы никого не запутать.   -  person petyusa    schedule 13.07.2020
comment
Можете ли вы включить код во все, что публикует сообщение, в методе концентратора   -  person auburg    schedule 13.07.2020
comment
Я добавил код сервера и сообщение, которое получаю от хаба.   -  person petyusa    schedule 13.07.2020
comment
Вы видите какие-либо ошибки в окне вывода отладки в Visual Studio при запуске приложения Blazor?   -  person auburg    schedule 13.07.2020
comment
Также попробуйте добавить асинхронность в свой обработчик: _hubConnection.On ‹IEnumerable ‹AccountResponse›› (accountschanged, async (accounts) = ›   -  person auburg    schedule 13.07.2020
comment
Нет ошибки в выводе или консоли браузера. Я пробовал добавить asnyc и ждать Task.CompletedTask в конце функции, но ничего не изменилось.   -  person petyusa    schedule 13.07.2020


Ответы (1)


Я наконец нашел проблему. Речь шла о сериализации полученного json-сообщения. Мне пришлось добавить .AddJsonProtocol() и настроить его, вот последний код:

_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();

Мне кажется странным, что я не получал сообщения об ошибке, кстати.

person petyusa    schedule 14.07.2020