I've written a generic hubs which I'm having some issues with so to debug it I've decided to make a simple connection count like so:
public class CRUDServiceHubBase<TDTO> : Hub, ICRUDServiceHubBase<TDTO>
{
public const string CreateEventName = "EntityCreated";
public const string UpdateEventName = "EntityUpdated";
public const string DeleteEventName = "EntityDeleted";
protected int _connectionCount = 0;
public Task Create(TDTO entityDTO)
{
return Clients.All.InvokeAsync(CreateEventName, entityDTO);
}
public Task Update(TDTO entityDTO)
{
return Clients.All.InvokeAsync(UpdateEventName, entityDTO);
}
public Task Delete(object[] id)
{
return Clients.All.InvokeAsync(DeleteEventName, id);
}
public override Task OnConnectedAsync()
{
this._connectionCount++;
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
this._connectionCount--;
return base.OnDisconnectedAsync(exception);
}
}
public class MessagesHub : CRUDServiceHubBase<MessageDTO>
{
public MessagesHub() : base()
{
}
}
I'm registering this class like so:
services.AddTransient<ICRUDServiceHubBase<MessageDTO>, MessagesHub>();
I have a service who is using this, which I'm using it's implementation factory to subscribing to it's events:
services.AddTransient<IMessageDTOService>( (c) => {
var context = c.GetRequiredService<DbContext>();
var adapter = c.GetRequiredService<IAdaptable<Message, IMessageDTO, MessageDTO>>();
var validator = c.GetRequiredService<IValidator<Message>>();
var entityMetadataService = c.GetRequiredService<IEntityMetadataService<Message>>();
var service = new MessageDTOService(context, adapter, validator, entityMetadataService);
var hub = c.GetService<ICRUDServiceHubBase<MessageDTO>>();
this.RegisterHubsCreate(service, hub);
return service;
});
When I go to fire the event I get a null reference:
Microsoft.AspNetCore.SignalR.Hub.Clients.get returned null.
My best guess is that because the service is a dependency for the controller, It's created before signalR can initialize It's clients?
Does anyone have a suggestion on how I can register my events, and have a client populated?
I turns out I needed to Inject the IHubContext into my hubs to have access to the clients when I want to invoke server side.
protected IHubContext<CRUDServiceHubBase<TDTO>> _context;
public CRUDServiceHubBase(IHubContext<CRUDServiceHubBase<TDTO>> context)
{
this._context = context;
}
public Task Create(TDTO entityDTO)
{
return this._context.Clients.All.InvokeAsync(CreateEventName, entityDTO);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With