Подключение к .Net Core 2.2 Web API-концентратору SignalR из .Net 4.8 Зависает клиент WPF - PullRequest
0 голосов
/ 11 июня 2019

У меня есть веб-API ASP .Net Core 2.2 с WPF-клиентом .Net 4.8, использующим API.Оба работают локально на моем ПК с Windows 10 в сообществе Visual Studio 2019.Я пытаюсь подключить клиент к основному интерфейсу API SignalR.Существует только односторонняя связь от сервера к клиентам.Клиенты никогда не будут отправлять данные на сервер.

На сервере у меня есть модель:

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 Ответ

1 голос
/ 11 июня 2019

Измените ваш обработчик (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();
       )
    ); 

И не используйте await для не асинхронных методов.Если вам нужен результат, вызовите «.Result» для задачи.

...