SignalR Core,客户端连接时未收到服务器响应

mic*_*cer 6 c# wpf signalr signalr.client asp.net-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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我将其初始化为单例:

    public MainWindowViewModel()
    {
        HubService.Instance.Initialize();
    }
Run Code Online (Sandbox Code Playgroud)

当我在调试时,在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在控制器的方法中以这种方式触发发送消息:

    [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);
    }
Run Code Online (Sandbox Code Playgroud)

正如我以前写的,而我调试我的WebApi,在Clients我从我只有一个连接WPF。当我关闭时WPFconnection count = 0连接工作完美。

但是当我打电话时SendAsync(),我没有收到 inWPF中的任何信息hubConnection.On。有趣的是,昨天它完美无缺。

那么,我的想法HubService是静态singleton的吗?如果它的,为什么我不能从recive消息WebApiSignalR当我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;
    }
Run Code Online (Sandbox Code Playgroud)

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"));
    }
Run Code Online (Sandbox Code Playgroud)

编辑2

这是我可以获得的连接,当我的客户WPF将注册他的连接时:

在此处输入图片说明

itm*_*nus 4

我在各种客户端(wpf/控制台/甚至使用浏览器)上尝试了您的代码,它对我来说总是工作得很好。hubConnection.On<string>("ReciveServerUpdate", update => {//todo});当我向 发送请求时,总是会调用PostTask.

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

  1. 您的PostTask([FromBody] Task task)操作方法未执行。假设这是一个方法,如果浏览器意外地发出带有of 的ApiController请求,则 的调用根本不会被执行。Content-Typeapplication/www-x-form-urlencodedClients.All.SendAsync(..., ...);
  2. SigalR 客户端 ( ) 的处理程序hubConnection.On<>(method,handler)必须具有与调用完全相同的参数列表才能接收消息。处理这个问题时我们必须非常小心。

  3. 最后,最好添加一个参考Microsoft.Extensions.Logging.Console

    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.*" />
    
    Run Code Online (Sandbox Code Playgroud)

    这样我们就可以启用日志记录来排除故障:

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