Отправка сообщения в SignalR из веб-API - PullRequest
1 голос
/ 08 января 2020

Я создал концентратор в своем веб-API. Это очень просто:

public class DashboardHub : Hub
{
    public async Task SendMessage(InfoSummary infoSummary)
    {
        await Clients.All.SendAsync("ReceiveMessage", infoSummary);
    }
}

Я пытаюсь отправить сообщение на концентратор с контроллера в том же веб-API при обновлении данных.

Я видел 100 разных ответов, и ничего не работает. По сути, мой объект-концентратор в контроллере имеет значение null, и я не могу его создать.

    private readonly IRepository _repo;
    private readonly Helpers.Convert _convert;
    private readonly CoreContext _context;
    private readonly IMapper _mapper;
    private readonly NotifyService _service;
    private readonly DashboardHub _hub;

    public MyController(IRepository repo, 
                                CoreContext context, 
                                IMapper mapper)
        {
            _convert = new Helpers.Convert(repo, mapper);
            _repo = repo;
            _context = context;
            _mapper = mapper;
            _hub = new DashboardHub();
            _service = new NotifyService(_hub);
        }

    [HttpPost("updatestatus")]
    public async Task<IActionResult> UpdateStatus(Header header) {

        var returnVal = await _repo.ChangeStatus(header.HeaderId, header.Status);

        headerSummary = _convert.ToReturnStatusHeader( await _repo.GetHeader(header.HeaderId));
        // await _service.SendNotificationAsync(headerSummary);
        await _hub.SendMessage(headerSummary);        

        return Ok(returnVal);
    }

У меня есть

services.AddSignalR();
services.AddScoped(typeof(DashboardHub));

и

endpoints.MapHub<DashboardHub>("/Hubs/DashboardHub");

в соответствующих разделах файла startup.cs

Я знаю, что упускаю что-то очень маленькое, но мне хотелось бы знать, что это такое.

Я также пытался создать сильно напечатал концентратор, но это принесло еще больше проблем.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 08 января 2020

Ну, я чувствую себя полным и полным новичком. Исправить это очень просто. Вы должны добавить инструкцию using, сообщающую контроллеру, что вы хотите использовать SignalR. О боже ... Я почти слишком смущен, чтобы с этим смириться, но надеюсь, что это поможет кому-то еще.

FIX:

using Microsoft.AspNetCore.SignalR;

: facepalm

0 голосов
/ 10 января 2020

Вы сделали там или четыре ошибки.

  1. Вам не нужна эта строка в вашем ConfigureServices методе Startup.cs . services.AddScoped(typeof(DashboardHub));

    Удалите его. Просто оставьте services.AddSignalR();

  2. Почему вы используете новое ключевое слово, поскольку. net ядро ​​обеспечивает встроенный сервис внедрения зависимостей. Удалите строки ниже.

    _hub = new DashboardHub();
    _service = new NotifyService(_hub); 
    

    Вместо этого создайте новый интерфейс INotifyService.cs для NotifyService.cs . Зарегистрируйте этот сервис в ConfigureServices метод Startup.cs .

    services.AddScoped<INotifyService, NotifyService>();

  3. Ваш MyController. cs должно быть как ниже

    Добавьте эту строку. using Microsoft.AspNetCore.SignalR;

    private readonly IRepository _repo;
    private readonly Helpers.Convert _convert;
    private readonly CoreContext _context;
    private readonly IMapper _mapper;
    private readonly INotifyService _service;
    private readonly IHubContext<DashboardHub> _hubContext

    public MyController(IRepository repo, CoreContext context, IMapper mapper,INotifyService service,IHubContext<DashboardHub> hubContext)
        {
            _convert = new Helpers.Convert(repo, mapper);
            _repo = repo;
            _context = context;
            _mapper = mapper;
            _service = service;
            _hubContext = hubContext;
        }

    [HttpPost("updatestatus")]
    public async Task<IActionResult> UpdateStatus(Header header) {

        var returnVal = await _repo.ChangeStatus(header.HeaderId, header.Status);

        headerSummary = _convert.ToReturnStatusHeader( await _repo.GetHeader(header.HeaderId));
        // await _service.SendNotificationAsync(headerSummary);

        await hubContext.Clients.All.SendAsync("ReceiveMessage", headerSummary);

        return Ok(returnVal);
    }
Используйте ту же концепцию, если вы отправляете сообщения внутри вашего NotifyService.cs.
0 голосов
/ 08 января 2020

Что вы можете сделать, это внедрить ваш хаб, используя внедрение зависимостей в вашем контроллере. Вы не можете просто создать экземпляр концентратора в контроллере, как вы делаете, и я бы изменил его на Singleton.

services.AddSingleton(typeof(DashboardHub));
internal DashboardHub DashboardHub
{
    get
    {
        return this.HttpContext.RequestServices.GetRequiredService<DashboardHub>();
    }
}
...