SignalR Core, не получает ответ от сервера, когда клиент подключен - PullRequest
4 голосов
/ 29 мая 2019

Я работаю над соединением 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"));
    }

EDIT2

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

enter image description here

1 Ответ

1 голос
/ 31 мая 2019

Я попробовал ваш код на всех типах клиентов (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();
    
...