We want a way to broadcast a message from the application service layer. However, signalR Hubs are only available in the Web layer. Therefore, we cannot call from a service into the Web layer. Using [https://aspnetboilerplate.com/Pages/Documents/Notification-System]) as a guide we have:
//server
public async Task PublishSaveAsync()
{
await _notificationPublisher.PublishAsync("message");
}
//client
function initializeHub() {
abp.event.on('abp.notifications.received', processSaved);
};
function processSaved(saveNotification) {
console.log('saveNotification', saveNotification);
};
The server code is executed, but the log statement is never written. Are we doing something incorrectly or is there a better way to do this?
Thanks.
5 Answer(s)
-
0
Why not create a generic hub interface in your app layer, implement it on your signalR hub, and then register that dependency in the web layer, and inject it in the app service?
-
0
Thanks @strix20 :)
-
0
@strix20 Thanks for the response. Here is our implementation below.
Generic Interface
public interface ISave<T> { void Save(T payload); }
Signal R Hub
[HubName("myHub")] public class MyHub: Hub, ITransientDependency, ISave<string> { /* https://aspnetboilerplate.com/Pages/Documents/SignalR-Integration#your-signalr-code */ public void Save(string payload) { Clients.Others.saved(payload); } }
App Service
public class MyAppService : AbpZeroTemplateAppServiceBase, IMyAppService { private readonly ISave<string> _hub; public MyAppService(ISave<string> hub) { _hub = hub; } public async Task<Result<Dictionary<long, long>>> SaveAsync(MasterCommandDto commands) { /* elided */ var payload = JsonConvert.SerializeObject(commands); _hub.Save(payload); // .. } }
public class AbpZeroTemplateWebModule : AbpModule { public override void Initialize() { IocManager.Register<ISave<string>, MyHub>(); } }
When we register the component in the Web layer we get this server error: Component MyCompanyName.AbpZeroTemplate.Web.Hubs.MyHub could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.
What is the appropriate way of adding this to the IOC container?
-
0
Register it in the PreInitialize method.
-
0
Thank you @aaron and @strix20. This works; wWe have our server-side payload from the application service via the Web's SignalR.