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

时间:2019-05-29 11:38:26

标签: c# wpf asp.net-core signalr signalr.client

我正在处理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()时,我没有收到WPFhubConnection.On中的任何信息。有趣的是,昨天它运行良好。

因此,我考虑将HubService设置为静态singleton是正确的吗?如果是这样,为什么当我的WebApi连接到SignalR时,我无法从WPF接收消息?

昨天我问过类似的问题,但是找到了解决方案。昨天,我的方法有效,当我收到hubConnection.On的任何消息时,我可以打WebApiMy question from yestarday

编辑

向控制器注入HUb

    private readonly ITaskService taskService;

    private readonly IHubContext<NotificationsHub> notificationsHub;

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

Startup.csSignalR事物(我删除了与信号无关的其他事物):

    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 个答案:

答案 0 :(得分:1)

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

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

  1. 您的PostTask([FromBody] Task task)操作方法未执行。假设这是一个ApiController方法,如果浏览器偶然发布了Content-Typeapplication/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();