Вызов метода Hub из действия контроллера в приложении ASPNetCore MVC с использованием SignalR - PullRequest
0 голосов
/ 12 июня 2018

Мне бы хотелось, чтобы веб-приложение ASPNetCore2.0, над которым я работаю, отправляло уведомление конкретным пользователям с помощью SignalR.Я хотел бы вызвать метод концентратора из действия другого контроллера (в отличие от вызова JS клиента).

Я узнал, что это не то, как SignalR предназначен для использования, но я нашел много пользователейу кого было такое же «желание», а также некоторые решения.Я проверил несколько предложенных решений, но самым простым и понятным, по-видимому, был принят ответ на этот пост: Получить Hub Context в SignalR Core из другого объекта .

Итак, я дал емуиди, и я не получаю ошибок вообще.Выходные данные сервера безошибочны, как и вкладки консоли браузера и сети (я использую Chrome).При отладке процесс проходит гладко, и программа делает именно то, что должна делать ... за исключением того, что пользователи не получают никаких уведомлений ...

Кто-нибудь из вас обнаружил проблему?

Я создал класс, который содержит общие методы для концентратора:

using Microsoft.AspNetCore.SignalR;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace WebApp.Hubs
{
    public class HubMethods
    {
        private readonly IHubContext<PostsHub> _hubContext;

        public HubMethods(IHubContext<PostsHub> hubContext)
        {
            _hubContext = hubContext;
        }

        public async Task Notify(string postId, string sender, List<string> users)
        {
            await _hubContext.Clients.Users(users).SendAsync("Notify", sender, postId);
        }
    }
}

Затем я создал концентратор:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace WebApp.Hubs
{
    [Authorize]
    public class PostsHub : Hub
    {
        private HubMethods _hubMethods;

        public PostsHub(HubMethods hubMethods)
        {
            _hubMethods = hubMethods;
        }

        public async Task Notify(string postId, string sender, List<string> users)
        {
            await _hubMethods.Notify(postId, sender, users);
        }
    }
}

Добавил эти биты в метод ConfigureServices при запуске:

[...]// Services before these...
services.AddSignalR();
services.AddScoped<HubMethods>();

services.AddMvc();

И метод настройки при запуске:

app.UseSignalR(routes =>
{
    routes.MapHub<PostsHub>("/postshub");
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

Затем эти строки для представления:

<script src="~/lib/signalr/signalr.js"></script>
@await Html.PartialAsync("_NotifyScriptsPartial")

И это "_NotifyScriptsPartial.cshtml":

<script>
    var connection = new signalR.HubConnectionBuilder().withUrl('/PostsHub').build();

    connection.on('Notify', function (sender, postId) {
        var post = postId;
        var sentBy = sender;
        var content = '<a href=\'#\' class=\'close\' data-dismiss=\'alert\' aria-label=\'close\'>&times;</a>' +
        'You just received a new comment from <strong>' +
        sentBy + '</strong>. Click <a href = \'#\' class=\'alert-link\' >here</a> to view the post.'
        var alert = document.createElement('div');
        alert.classList.add('alert', 'alert-info', 'alert-dismissible');
        alert.html(content);
        document.getElementById('pageContent').appendChild(alert);
    });
</script>

Наконец, в контроллере, который должен отправлять уведомления, я добавил:

public class PostsController : Controller
{
    private readonly HubMethods _hubMethods;

    public PostsController(HubMethods hubMethods)
    {
        _hubMethods = hubMethods;
    }

    // POST: Create a new post
    [Authorize]
    [HttpPost]
    public async Task<IActionResult> Create(DetailsModel model, List<string> readers)
    {
        if (ModelState.IsValid)
        {

        // Do stuff here... including creating the newPostId, userId and receipients variables used below

            await _hubMethods.Notify(newPostId, userId, receipients);

            // Do more stuff and eventually...

            return View();
        }
    }
}

Есть идеи?

1 Ответ

0 голосов
/ 14 августа 2018

В Asp.Net Core 2.1 я могу использовать такой концентратор, это решает мою проблему, также вы использовали это в своем контроллере.Надеюсь, это поможет.

public class SomeController : Controller
{
    private readonly IHubContext<MyHub> _myHub;

    public SomeController (IHubContext<MyHub> myHub)
    {
        _myHub = myHub;
    }

    public void SomeAction()
    {
        //for your example 
        _myHub.Clients.All.SendAsync("Notify", "data");
    }
}

Я могу получить текст «данных» из консоли браузера.Если вы используете jQuery в своем проекте, добавьте эти коды между jQuery(document).ready(function () { });, потому что вы пытались загрузить частичный HTML, и я думаю, что ваш код должен запускаться после события ready ().Извините, если я вас неправильно понял.

...