Taylor Mitchell Taylor Mitchell - 2 months ago 12
C# Question

Signalr not working from controller, I assume it's not finding clients

I'm trying to broadcast a message from a controller. Basically what I'm trying to do is send a notification to everyone's dashboard whenever a specific object is saved. In my JS I have the connect method and I can send messages to the server and get messages back from it, so I know I'm connected to the hub, however in my controller using the

GlobalHost.ConnectionManager.GetHubContext<MyHub>()
method to get the context it doesn't seem to send to any of the clients.

Hub

public class UpdateHub : Hub
{
public void Update()
{
Clients.All.update("You've reached the hub");
}
}


Controller(after my model is saved, but before returning the view, the model saves, and it runs)

var updateHubContext = GlobalHost.ConnectionManager.GetHubContext<UpdateHub>();
updateHubContext.Clients.All.update("A new model has been saved");


Debugging on the update method revealed...

updateHubContext.Clients.All.update("A new model has been saved");
Id = 1714, Status = RanToCompletion, Method = "{null}", Result = ""
AsyncState: null
CancellationPending: false
CreationOptions: None
Exception: null
Id: 1714
Result: null
Status: RanToCompletion


But if it ran to completion why didn't the client see it? If I send the update method to the server the client then sees it.

var myhub = $.connection.notificationHub;
myhub.server.Update();
myhub.client.update = function(message) {
alert(message);
}
$.connection.hub.start();


any ideas where I'm going wrong here?

Also I'm using Autofac, I don't think the issue is there, but here's the code for it.

var config = new HubConfiguration();
var builder = new ContainerBuilder();

builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterHubs(Assembly.GetExecutingAssembly()).SingleInstance();
var container = builder.Build();
config.Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container);

app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
app.MapSignalR("/signalr", config);

ConfigureAuth(app);

Answer

I needed to inject a lifetime scope into it for Autofac.

private readonly ILifetimeScope _hubLifetimeScope;
public UpdateHub(ILifetimeScope lifetimeScope)
{
    _hubLifetimeScope = lifetimeScope.BeginLifetimeScope("AutofacWebRequest");
}

It's in the docs. Also I needed to Register the Hubs with Autofac individually and as ExternallyOwned.

Comments