SignalR Core, не получая ответа от сервера при подключении клиента

Я работаю над подключением SignalR Clinet-Server. Мой сервер WebApi Core 2.1, а мой клиент WPF .NET Framework 4.7.2.

На стороне клиента у меня есть концентратор singleton с одним экземпляром для получения сообщений с сервера:

using System.Collections.ObjectModel;
using Microsoft.AspNetCore.SignalR.Client;

public class HubService
{
    //singleton
    public static HubService Instance { get; } = new HubService();

    public ObservableCollection<string> Notifications { get; set; }

    public async void Initialize()
    {
        this.Notifications = new ObservableCollection<string>();

        var hubConnection = new HubConnectionBuilder()
            .WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
            .Build();

        hubConnection.On<string>("ReciveServerUpdate", update =>
        {
            //todo
        });

        await hubConnection.StartAsync();
    }
}

я инициализирую его как синглтон:

    public MainWindowViewModel()
    {
        HubService.Instance.Initialize();
    }

Пока я отлаживаю, на MainWindowViewModel я нажимаю на это HubService.

Со стороны Server это выглядит так.

Hub:

using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

public class NotificationsHub : Hub
{
    public async Task GetUpdateForServer(string call)
    {
        await this.Clients.Caller.SendAsync("ReciveServerUpdate", call);
    }
}

Я запускаю отправку сообщения таким образом в методах моего контроллера:

    [HttpPost]
    public async Task<IActionResult> PostTask([FromBody] Task task)
    {
        if (!this.ModelState.IsValid)
        {
            return this.BadRequest(this.ModelState);
        }

        this.taskService.Add(task);

        //here im calling sending message. When im debugging
        //i see one connection from my WPF with unique ConnectionId
        await this.notificationsHub.Clients.All.SendAsync("ReciveServerUpdate", "New Task in database!");

        return this.Ok(task);
    }

Как я уже писал ранее, пока я отлаживаю свой WebApi, в Clients у меня ровно одно подключение от моего WPF. Когда я выключаю WPF, connection count = 0 соединения работают отлично.

Но когда я звоню SendAsync(), я не получаю никакой информации в WPF в hubConnection.On. Забавно, вчера работало отлично.

Итак, правильно ли я думаю о том, чтобы сделать HubService статичным singleton? Если да, то почему я не могу получать сообщения от WebApi от SignalR, когда к нему подключен мой WPF?

Я спросил что-то подобное вчера, но я нашел решение для этого. Вчера мои методы работали, я мог нажать hubConnection.On, когда получил сообщение от WebApi. Мой вчерашний вопрос.

РЕДАКТИРОВАТЬ

Ввод HUb в контроллер:

    private readonly ITaskService taskService;

    private readonly IHubContext<NotificationsHub> notificationsHub;

    public TaskController(ITaskService taskService, IHubContext<NotificationsHub> notificationsHub)
    {
        this.taskService = taskService;
        this.notificationsHub = notificationsHub;
    }

И Startup.cs только SignalR вещи (все остальное, не относящееся к сигналу, я удалил):

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
        services.AddSignalR();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseSignalR(routes => routes.MapHub<NotificationsHub>("/Notifications"));
    }

РЕДАКТИРОВАТЬ2

Вот соединение, которое я могу получить, когда мой клиент WPF зарегистрирует свое соединение:

SignalR Core, не получая ответа от сервера при подключении клиента

Покажите код, как вы внедрили NotificationsHub в свой контроллер.

TanvirArjel 29.05.2019 14:24

@TanvirArjel я тоже добавил Startup.cs (только с signalR). Загляни в мою правку

michasaucer 29.05.2019 14:28

Что я знаю, когда у меня есть что-то вроде static Instance с { get; } = New, это должно работать как синглтон, в этом случае я хотел добиться постоянного Hub получения сообщений от Webapi, когда кто-то вызывает Post действие

michasaucer 29.05.2019 14:32

Я пробовал ваш код со всеми типами клиентов (wpf/консоль/даже с браузером), он всегда работает нормально для меня. hubConnection.On<string>("ReciveServerUpdate", update => {//todo}); всегда вызывается, когда я отправляю запрос на PostTask. Есть ли минимальная демо, которая воспроизводит?

itminus 30.05.2019 10:32

Потому что... это работает! Я просто не знал, что во время отладки я не могу получить доступ к методу hub.On ... Итак, мне нужно закрыть этот вопрос или просто оставить его следующим поколениям? Вы правы @itminus. Я просто потерял много времени, пытаясь отладить его.

michasaucer 30.05.2019 10:38

:) Это действительно вопрос Шредингера .... Я считаю, что если вы не можете воспроизвести ту же проблему, лучше обновить свой вопрос, чтобы напомнить кому-то, кто хочет провести расследование. Но не удаляйте этот вопрос, если это ошибка, которую мы пока не заметили.

itminus 30.05.2019 10:44

Я считаю, вы можете опубликовать ответ. Я отмечу это, потому что это помогает tbh

michasaucer 30.05.2019 10:49

Не могли бы вы сказать мне, что ваш экземпляр отладчика VS попадает в hubConnnection.On? Потому что я заполнил Notificationsupdates из этого метода, и отладчик, когда я разместил задачу, не активировал мою точку останова, но список Notifications был заполнен

michasaucer 30.05.2019 10:51

@michasaucer Да. Точка останова срабатывает как в VS, так и в VSCode.

itminus 30.05.2019 10:55

@michasaucer Когда вы говорите «не сработала моя точка останова», как вы настраиваете аргументы обработчика? Количество аргументов должно быть одинаковым.

itminus 30.05.2019 10:59

Я только что установил точку останова в hubConnection.On, и она никогда не срабатывает. Когда я просто проверял, что в Notifications, были сообщения от Webapi, отправленные хабом

michasaucer 30.05.2019 11:19

Давайте продолжить обсуждение в чате.

itminus 30.05.2019 11:21

@michasaucer Вы перезапускали клиент при отладке?

itminus 30.05.2019 11:30

@itminus спасибо, что потратили свое время. Пожалуйста, напишите ответ, чтобы я пометил его как решение моей проблемы.

michasaucer 30.05.2019 17:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
14
3 165
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я пробовал ваш код со всеми типами клиентов (wpf/console/даже с браузером), у меня он всегда работает нормально. hubConnection.On<string>("ReciveServerUpdate", update => {//todo}); всегда вызывается, когда я отправляю запрос на PostTask.

Я не уверен, почему (иногда) это у вас почему-то не работает. Однако, когда клиент SignalR подключается к серверу, но не получает сообщения от сервера, возможны две причины:

  1. Ваш метод действия PostTask([FromBody] Task task) не выполнен. Допустим, это метод ApiController, если браузер случайно отправит запрос с Content-Type из application/www-x-form-urlencoded, вызов Clients.All.SendAsync(..., ...); вообще не будет выполнен.
  2. Обработчик клиента SigalR (hubConnection.On<>(method,handler)) должен иметь точно такой же список аргументов, что и вызов, чтобы получать сообщения. Мы должны быть очень осторожны, имея дело с этим.

  3. Наконец, лучше добавить ссылку на Microsoft.Extensions.Logging.Console

    <PackageReference Include = "Microsoft.Extensions.Logging.Console" Version = "2.2.*" />
    

    чтобы мы могли включить ведение журнала для устранения неполадок:

    var hubConnection = new HubConnectionBuilder()
        .WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
        .ConfigureLogging(logging =>{
            logging.AddConsole();        // enable logging
        })
        .Build();
    

Пожалуйста, укажите, что мой код работает в вашем ответе для следующего поколения разработчиков .NET (некоторые из них сразу погружаются в ответы)

michasaucer 31.05.2019 09:12

Другие вопросы по теме