SignalR Core,连接客户端时未从服务器获得响应

SignalR Core, not getting response from server when client is connected

我正在处理 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。当我关闭 WPFconnection count = 0 时,连接工作正常。

但是当我调用 SendAsync() 时,我没有在 hubConnection.On 中收到 WPF 中的任何信息。有趣的是,昨天它完美运行。

那么,我关于将 HubService 设为静态 singleton 的想法是否正确?如果是,为什么当我的 WPF 连接到它时,我无法通过 SignalR 接收来自 WebApi 的消息?

我昨天问了一些类似的问题,但我找到了解决方案。昨天,我的方法奏效了,当我收到来自 WebApi 的任何消息时,我可以点击 hubConnection.On

编辑

向控制器注入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 将注册他的连接时:

我用各种客户端(wpf/console/even 用浏览器)试过你的代码,它对我来说总是很好用。当我向 PostTask.

发送请求时,总是会调用 hubConnection.On<string>("ReciveServerUpdate", update => {//todo});

我不确定为什么(有时)它对您不起作用。但是,当 SignalR 客户端连接到服务器但没有收到来自服务器的消息时,可能有两个原因:

  1. 您的 PostTask([FromBody] Task task) 操作方法未执行。假设这是一个 ApiController 方法,如果浏览器不小心发出一个带有 application/www-x-form-urlencodedContent-Type 的请求,则根本不会执行 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();