c# - new - signalr core javascript
El método de cliente de llamadas SignalR desde un hub externo usando GlobalHost.ConnectionManager.GetHubContext no funciona. Pero llamar desde el centro lo hace (2)
Me encontré con el mismo problema hace unos días. Eso tomó mis 2 días para encontrar la solución y resolverla. Después de investigar seriamente, la causa raíz de los problemas fue la resolución de la dependencia del señalizador que configuré de forma personalizada.
Al final encontré este enlace y eso decía esto:
Reemplazar el DependencyResolver
Puede cambiar DependencyResolver para usar su contenedor DI de elección configurando GlobalHost.DependencyResolver.
NOTA: NO anule la resolución global en PreApplicationStart, no funcionará, o solo funcionará algunas veces. Hazlo en PostApplicationStart (usando WebActivator) o en Global.asax.
El lugar importante aquí es la NOTA. Por supuesto, después de signalr 2.0, esta documentación quedará obsoleta . Así que mezclé algo de aquí con la nueva API SignalR. En la nueva SignalR API ya no usa WebActivatorEx. OwinStartup preferido en lugar de 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);
}
}
}
Y en su 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);
}
}
}
No quiero enviar todo el código aquí, para mostrar el problema real.
Entonces, para mí, todo funciona bien por ahora. La inyección de dependencia también funciona también. Pero la parte mala está en todas partes que busqué David Fowler decía "Es por diseño". Empecé a pensar que este diseño es realmente necesario o un error.
Espero que ayude a alguien más que hace la investigación para el mismo problema.
Intento llamar a un método de cliente desde una acción de controlador .NET Web API.
¿Puedo hacer esto?
La única publicación que encuentro que se acerca a lo que estoy buscando hacer es esta:
SignalR + publicar un mensaje a un concentrador a través de un método de acción
Allí se envía un mensaje desde una acción de controlador asp.net MVC utilizando GlobalHost.ConnectionManager.GetHubContext.
Cuando intento eso dentro de mi acción de API web no se producen errores, pero el método "methodInJavascript" nunca se invoca en el lado del cliente.
Public ActionResult MyControllerMethod()
{
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.methodInJavascript("hello world");
// or
context.Clients.Group("groupname").methodInJavascript("hello world");
}
Cuando establezco un punto de interrupción dentro de esa acción, veo que el código se está alcanzando y se está ejecutando. Sin embargo, nada sucede en el lado del cliente de JavaScript.
¿Por qué? ¿La API web es tan diferente bajo el capó que esto no funcionará? ¿Alguien más lo intentó y tuvo éxito?
Cuando llamo a "methodInJavascript" desde "dentro" de mi hub, funciona perfectamente. Simplemente no funcionará cuando se lo llame desde dentro de una acción del controlador .NET Web API.
ACTUALIZAR:
Después de investigar este problema, no tengo solución. Solo puedo suponer que hay algo que falta en ejemplos como este Servidor a los mensajes del cliente que no pasan con SignalR en ASP.NET MVC 4 y este llamando a SignalR hub desde el controlador WebAPI emite tal vez un paso de configuración adicional para habilitar las llamadas desde un HubContext o algo. El código que inicialmente publiqué aquí es similar al que aparece en esos ejemplos y no se ha demostrado que sea defectuoso de ninguna manera. ¿Alguien puede ver un error en el código? Llamando desde html funciona. Lo hago extensamente en mis aplicaciones y nunca tengo problemas. Nunca he visto una llamada de HubContext en un controlador API funcionar. Sin errores. Simplemente no hay resultados en el cliente.
SOLUCIONADO (tipo de):
El código anterior sí funciona como está cuando se publicó . Sin embargo, no funciona en el entorno de desarrollo de Visual Studio a través de localhost. Sin errores pero sin resultado en el extremo del cliente. Publicar el código tal como está en un servidor real en la web sí funciona. Nunca pensé que hubiera una diferencia así que nunca lo intenté. Me imaginé que si no funcionaba localmente no funcionaría publicado. Está funcionando en vivo ahora, pero me pregunto por qué no funciona a través de localhost en el entorno de desarrollo. No se puede probar localmente con puntos de interrupción y tal.
Tengo la sensación de que es ese directorio virtual del transmisor. Algo es diferente cuando se ejecuta localmente versus publicado. No estoy seguro de qué, pero veo muchas publicaciones como http://www.bitwisejourneys.com/signalr-hosting-in-iis-a-nasty-gotcha/ . Leer ahora para ver si hay una forma de que funcione tanto localmente como publicado.
Tuve el mismo problema, y está relacionado con IoC (con cualquier cosa como ninject o castle). Si configura el resolvedor de dependencias global a su administrador de IoC, también reemplazará la resolución de canalización interna de SignalR. Esto hace que su hub de cliente SingleTon no funcione correctamente.
Lo resolví teniendo solo Server Hubs siendo IoC-ed El siguiente código requiere SignalHubActivator (puedes encontrarlo en Internet)
Ahora, GlobalHost.ConnectionManager.GetHubContext devolverá la instancia única Y los métodos del cliente volverán a llamarse correctamente.
//configuration.Resolver = signalrDependency ; dont, this will cause GlobalHost.ConnectionManager to be intercepted by Castle
configuration.Resolver.Register(typeof(IHubActivator),
() => new SignalHubActivator(container));