Подтвердить что ты не робот

Вызов метода вызова SignalR из внешнего концентратора с использованием метода GlobalHost.ConnectionManager.GetHubContext не работает. Но вызов изнутри концентратора

Я пытаюсь вызвать клиентский метод из действия контроллера .net Web API.

Могу ли я это сделать?

Единственный пост, который я могу найти, который близок к тому, что я ищу, - это:

SignalR + отправка сообщения в концентратор с помощью метода действий

В нем сообщение отправляется из действия контроллера MVC asp.net с использованием GlobalHost.ConnectionManager.GetHubContext.

Когда я пытаюсь, что внутри моего действия по веб-API не возникают ошибки, но метод "methodInJavascript" никогда не вызывается на стороне клиента.

    Public ActionResult MyControllerMethod()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        context.Clients.All.methodInJavascript("hello world");
        // or
        context.Clients.Group("groupname").methodInJavascript("hello world");
    }

Когда я устанавливаю точку прерывания внутри этого действия, я вижу, что код выполняется и выполняется. Однако ничего не происходит на стороне клиента javascript.

Почему? Является ли веб-API таким разным под капотом, что это не сработает? Кто-нибудь еще пробовал это и имел успех?

Когда я вызываю "methodInJavascript" из "внутри" моего концентратора, он работает отлично. Просто не будет работать при вызове из действия контроллера .net Web API.

UPDATE:

После изучения этой проблемы у меня нет решения. Я могу только предположить, что в таких примерах что-то не хватает, чтобы сообщения клиентов не проходили через SignalR в ASP.NET MVC 4, и это вызывает концентратор SignalR из проблем контроллера WebAPI, например, возможно, есть дополнительный шаг настройки, позволяющий вызывать из HubContext или что-то еще. Код, который я изначально размещал здесь, похож на тот, который появляется в этих примерах, не был продемонстрирован как-то испорченный. Может ли кто-нибудь увидеть недостатки в коде? Вызов из html работает. Я делаю это широко в своих приложениях и никогда не испытываю проблемы. Я никогда не видел вызова из HubContext в работе контроллера API. Нет ошибок. Просто никаких результатов на клиенте.

РЕШЕННЫЙ (вид):

Код выше действительно работает как при публикации. Однако не работает в среде Visual Studio dev через localhost. Ошибок нет, но результат не заканчивается. Публикация кода, как и реального сервера в Интернете, действительно работает. Я никогда не думал, что будет разница, поэтому я никогда не пробовал. Если он не работает локально, он не будет опубликован. Теперь он работает, но мне интересно, почему он не работает через localhost в среде dev. Не удается проверить локально с точками останова и т.д.

У меня такое чувство, что это виртуальный каталог signalr. Что-то другое при запуске локально и опубликовано. Не уверен, что, но я вижу много сообщений, таких как http://www.bitwisejourneys.com/signalr-hosting-in-iis-a-nasty-gotcha/. Читайте сейчас, чтобы узнать, есть ли способ заставить его работать как локально, так и публично.

4b9b3361

Ответ 1

Я столкнулся с той же проблемой пару дней назад. Это заняло у меня 2 дня, чтобы найти решение и решить проблему. После некоторого серьезного расследования основной причиной проблем стал распознаватель зависимостей signalr, который я задал на заказ.

В конце я нашел эту ссылку, и это говорило следующее:

Замена DependencyResolver

Вы можете изменить DependencyResolver для использования вашего контейнера DI выбор путем установки GlobalHost.DependencyResolver.

ПРИМЕЧАНИЕ. НЕ переопределяйте глобальный преобразователь в PreApplicationStart, это не будет работать, или он будет работать только иногда. Сделайте это в PostApplicationStart (с использованием WebActivator) или в Global.asax.

Важное место здесь ПРИМЕЧАНИЕ. Конечно, после signalr 2.0 эта документация становится устаревшей. Поэтому я немного смешал с новым SignalR API. В новом SignalR API больше не используется WebActivatorEx. OwinStartup предпочитает вместо WebActivator.

[assembly: OwinStartupAttribute(typeof(YourNamespace.Startup))]
namespace YourNamespace
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //IoC container registration process
            UnityConfig.RegisterComponents();

            UnityConfig.Container.RegisterType<AHub, AHub>();

            HubConfiguration config = new HubConfiguration();
            config.EnableJavaScriptProxies = true;


            //You should remove your dependency resolver code from here to Global.asax Application_Start method. Before setting the MVC properties.
            //config.Resolver = new SignalrDefaultDependencyResolver(UnityConfig.Container); // your dependency resolver
            //


            app.MapSignalR(config);
        }
    }
}

И в вашем global.asax

namespace YourNamespace
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            //Here your SignalR dependency resolver
            GlobalHost.DependencyResolver = new SignalrDefaultDependencyResolver(UnityConfig.Container);


            //other settings goes on
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

Я не хочу отправлять весь код здесь, чтобы показать реальную проблему.

Так что для меня все работает отлично. Также работает инъекция зависимостей. Но плохая часть везде, где я искал Дэвида Фаулера, говорил "Его по дизайну". Я начал думать, что этот дизайн действительно является необходимой или ошибкой.

Надеюсь, что это поможет кому-то другому, кто занимается исследованиями по той же проблеме.

Ответ 2

У меня была такая же проблема, и она связана с IoC (с любым типом, например, ninject или castle). Если вы установите глобальный преобразователь зависимостей на ваш менеджер IoC, он также заменит разрешение внутреннего конвейера SignalR. Это делает ваш клиентский концентратор SingleTon неработоспособным.

Я решил это, только имея серверные хабы, имеющие IoC-ed Для этого кода требуется SignalHubActivator (вы можете найти его в Интернете)

Теперь GlobalHost.ConnectionManager.GetHubContext вернет один экземпляр И клиентские методы будут снова вызваны правильно!

 //configuration.Resolver = signalrDependency ; dont, this will cause GlobalHost.ConnectionManager to be intercepted by Castle


 configuration.Resolver.Register(typeof(IHubActivator),
                                      () => new SignalHubActivator(container));