从.Net 4.8 WPF客户端连接到.Net Core 2.2 Web API SignalR集线器时挂起

时间:2019-06-10 21:39:09

标签: .net wpf signalr asp.net-core-webapi signalr.client

我有一个ASP .Net Core 2.2 Web API和一个使用该API的.Net 4.8 WPF客户端。两者都在Visual Studio 2019社区中的Windows 10 PC上本地运行。我正在尝试将客户端连接到API的SignalR Core Hub。从服务器到客户端只有单向通信。客户端将永远不会将数据发送到服务器。

在服务器上,我有一个模型:

public partial class Reading
{
    public int Id { get; set; }
    public int? BaseId { get; set; }
    public double? Frequency { get; set; }
    public byte? Modulation { get; set; }
    public byte? Agc1 { get; set; }
    public byte? Agc2 { get; set; }
    public DateTime TimeStamp { get; set; }
}

和强类型集线器:

public interface IChatClient
{
    Task ReceiveMessage(int id, int? baseId, double? frequency, byte? modulation, byte? agc1, byte? agc2, DateTime timeStamp);
}

public class StronglyTypedChatHub : Hub<IChatClient>
{
    public async Task SendMessage(Reading reading)
    {
        await Clients.All.ReceiveMessage(reading.Id, reading.BaseId, reading.Frequency, reading.Modulation, reading.Agc1, reading.Agc2, reading.TimeStamp);
    }

    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await base.OnDisconnectedAsync(exception);
    }
}

在API的一个控制器中,我想将数据发送到所有连接的客户端:

[Route("api/Readings")]
public class ReadingsController : Controller
{
    private readonly DbContext _context;
    private readonly IHubContext<StronglyTypedChatHub, IChatClient> _hubContext;

    public ReadingsController(DbContext context, IHubContext<StronglyTypedChatHub, IChatClient> hubContext)
    {
        _context = context;
        _hubContext = hubContext;
    }

    [HttpPost]
    public async Task<IActionResult> PostReading([FromBody] Reading reading)
    {
        _context.Readings.Add(reading);
        await _context.SaveChangesAsync();

        await _hubContext.Clients.All.ReceiveMessage(reading.Id, reading.BaseId, reading.Frequency, reading.Modulation, reading.Agc1, reading.Agc2, reading.TimeStamp);

        return CreatedAtAction("GetReading", new { id = reading.Id }, reading);
    }

在Startup.cs中:

    services.AddSignalR(options =>
    {
        options.EnableDetailedErrors = true;
    });

    app.UseSignalR(route =>
    {
        route.MapHub<StronglyTypedChatHub>("/chathub");
    });

我在客户端上有

    using Microsoft.AspNetCore.SignalR.Client;

    private HubConnection hubConnection { get; set; }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        hubConnection = new HubConnectionBuilder()
        .WithUrl("http://localhost:44368/chatHub")
        .Build();

        hubConnection.Closed += async (error) =>
        {
            await Task.Delay(new Random().Next(0, 5) * 1000);
            await hubConnection.StartAsync();
        };

        await hubConnection.StartAsync();

        hubConnection.On<int, int?, byte?, double?, byte?, byte?, byte?, DateTime>("SendMessage", (id, baseId, frequency, modulation, agc1, agc2, timeStamp) =>
           this.Dispatcher.Invoke(() =>
               CallSomeMethod();
           )
        ); 
    }

我将Visual Studio解决方案配置为启动两个项目,然后按F5。 API运行。然后客户端运行,但挂在await hubConnection.StartAsync();上 没有错误消息或任何东西。它只是挂在那里。当API的控制器方法触发并将数据发送到集线器时,客户端不会收到任何信息。客户端上没有任何触发。我猜是因为它挂在await hubConnection.StartAsync();

我是SignalR的新手。我会出错的任何想法将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

在客户端更改处理程序(hubConnection.On)。您注册的方法是错误的。在集线器上,您正在向所有客户端发送“ ReceiveMessage”,而在客户端上,您已注册“ SendMessage”。选择1,但我建议使用“ SendMessage”,因为从集线器发送数据会更有意义。

hubConnection.On<int, int?, byte?, double?, byte?, byte?, byte?, DateTime>("SendMessage"//change this, (id, baseId, frequency, modulation, agc1, agc2, timeStamp) =>
       this.Dispatcher.Invoke(() =>
           CallSomeMethod();
       )
    ); 

并且不要在非异步方法上使用等待。如果需要结果,请在任务上调用“ .Result”。