diff --git a/Constants/XWebinarHubAction.cs b/Constants/XWebinarHubAction.cs index 3d75696..f58f6b5 100644 --- a/Constants/XWebinarHubAction.cs +++ b/Constants/XWebinarHubAction.cs @@ -2,6 +2,9 @@ using xExceptions.Attributes; namespace xWebinarService.Constants { + /// + /// Webinar Connection Hub Actions ... + /// public enum XWebinarHubAction { /// @@ -21,17 +24,28 @@ namespace xWebinarService.Constants /// [StringValue("ViewerJoined")] ViewerJoined, - + /// /// When a Webinar Subscriber Leaved a Webinar ... /// [StringValue("ViewerLeaved")] ViewerLeaved, - + /// /// Send a Message to Webinar ... /// [StringValue("Message")] Message, } + + /// + /// Entity Hub Actions ... + /// + public enum XWebinarEntityHubAction + { + [StringValue("Subscribed")] + Subscribed, + [StringValue("Unsubscribe")] + Unsubscribe + } } \ No newline at end of file diff --git a/Hubs/XWebinarEntityHub.cs b/Hubs/XWebinarEntityHub.cs new file mode 100644 index 0000000..c96bc81 --- /dev/null +++ b/Hubs/XWebinarEntityHub.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Extensions.Logging; +using xPushService.Base; +using xWebinarService.Models.Entities; + +namespace xWebinarService.Hubs +{ + public class XWebinarEntityHub : XBaseEntityHub + { + // + #region Constructor ... + public XWebinarEntityHub(ILogger logger) : base(logger) + { } + #endregion + } +} \ No newline at end of file diff --git a/Interfaces/IXWebinarProvider.cs b/Interfaces/IXWebinarProvider.cs index 4046357..d2e5106 100644 --- a/Interfaces/IXWebinarProvider.cs +++ b/Interfaces/IXWebinarProvider.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR; using xDataService.Configuration; using xIdentityService.Interfaces; using xModels.Dtos; +using xWebinarService.Hubs; using xWebinarService.Interfaces.Entities; using xWebinarService.Models.Dtos; using xWebinarService.Models.Entities; @@ -14,6 +16,7 @@ namespace xWebinarService.Interfaces { // #region Props ... + IHubContext Hub { get; } IXIdentityProvider IdentityProvider { get; } IXWebinarRepository WebinarRepository { get; } XDataServiceConfiguration DataSercviceConfiguration { get; } @@ -46,15 +49,23 @@ namespace xWebinarService.Interfaces /// Create Webinar ... /// /// + /// /// - Task CreateWebinar(XWebinarDto item); + Task CreateWebinar( + XWebinarDto item, + string connectionId = null + ); /// /// Update a Webinar ... /// /// + /// /// - Task UpdateWebinar(XWebinarDto item); + Task UpdateWebinar( + XWebinarDto item, + string connectionId = null + ); /// /// Retrieve Specified Webinar ... @@ -93,8 +104,12 @@ namespace xWebinarService.Interfaces /// Remove Specified Webinar ... /// /// + /// /// - Task RemoveWebinar(Guid webinarId); + Task RemoveWebinar( + Guid webinarId, + string connectionId = null + ); #endregion // @@ -104,10 +119,12 @@ namespace xWebinarService.Interfaces /// /// /// + /// /// Task Subscribe( Guid webinarId, - string subscriberId + string subscriberId, + string connectionId = null ); /// @@ -126,10 +143,12 @@ namespace xWebinarService.Interfaces /// /// /// + /// /// Task Unsubscribe( Guid webinarId, - string subscriberId + string subscriberId, + string connectionId = null ); /// diff --git a/Providers/XWebinarProvider.cs b/Providers/XWebinarProvider.cs index 0200362..a0becc9 100644 --- a/Providers/XWebinarProvider.cs +++ b/Providers/XWebinarProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR; using xCommons.Extensions; using xDataService.Configuration; using xDataService.Extensions; @@ -10,7 +11,9 @@ using xIdentityModels.Dtos; using xIdentityService.Extensions; using xIdentityService.Interfaces; using xModels.Dtos; +using xPushService.Constants; using xWebinarService.Constants; +using xWebinarService.Hubs; using xWebinarService.Interfaces; using xWebinarService.Interfaces.Entities; using xWebinarService.Models.Dtos; @@ -25,6 +28,7 @@ namespace xWebinarService.Providers { // #region Props ... + public IHubContext Hub { get; } public IXIdentityProvider IdentityProvider { get; } public IXWebinarRepository WebinarRepository { get; } public XDataServiceConfiguration DataSercviceConfiguration { get; } @@ -41,7 +45,8 @@ namespace xWebinarService.Providers XDataServiceConfiguration dataSercviceConfiguration, IXWebinarTitleResourceProvider titleResourceProvider, IXWebinarSubscriberRepository webinarSubscriberRepository, - IXWebinarDescriptionResourceProvider descriptionResourceProvider + IXWebinarDescriptionResourceProvider descriptionResourceProvider, + IHubContext hub = null ) { // @@ -51,6 +56,7 @@ namespace xWebinarService.Providers TitleResourceProvider = titleResourceProvider; WebinarSubscriberRepository = webinarSubscriberRepository; DescriptionResourceProvider = descriptionResourceProvider; + Hub = hub; } #endregion @@ -163,8 +169,12 @@ namespace xWebinarService.Providers /// Create Webinar ... /// /// + /// /// - public async Task CreateWebinar(XWebinarDto item) + public async Task CreateWebinar( + XWebinarDto item, + string connectionId = null + ) { // // Validate ... @@ -276,6 +286,13 @@ namespace xWebinarService.Providers XException.ActionFailed.Throw(); } + // + await SendPush( + action: XBaseEntityHubAction.Add.GetStringValue(), + payLoad: entity.ToJSON(), + connectionId: connectionId + ); + // // Convert Entity to Dto ... var result = await ToXWebinarDto(entity); @@ -286,8 +303,12 @@ namespace xWebinarService.Providers /// Update a Webinar ... /// /// + /// /// - public async Task UpdateWebinar(XWebinarDto item) + public async Task UpdateWebinar( + XWebinarDto item, + string connectionId = null + ) { // // Validate ... @@ -413,8 +434,20 @@ namespace xWebinarService.Providers ); // + entity = await WebinarRepository.GetAsync(entity.Id); var result = await ToXWebinarDto(entity); + // + if (!result.IsNullOrDefault()) + { + // + await SendPush( + action: XBaseEntityHubAction.Update.GetStringValue(), + payLoad: entity.ToJSON(), + connectionId: connectionId + ); + } + // return result; } @@ -615,9 +648,11 @@ namespace xWebinarService.Providers /// Remove Specified Webinar ... /// /// + /// /// public async Task RemoveWebinar( - Guid webinarId + Guid webinarId, + string connectionId = null ) { // @@ -668,6 +703,15 @@ namespace xWebinarService.Providers // // Check Entity Removed ... result = !await WebinarRepository.IsExistsAsync(webinarId); + if (result) + { + // + await SendPush( + action: XBaseEntityHubAction.Delete.GetStringValue(), + payLoad: entity.ToJSON(), + connectionId: connectionId + ); + } // return result; @@ -681,10 +725,12 @@ namespace xWebinarService.Providers /// /// /// + /// /// public async Task Subscribe( Guid webinarId, - string subscriberId + string subscriberId, + string connectionId = null ) { // @@ -750,6 +796,15 @@ namespace xWebinarService.Providers }; entity = await WebinarSubscriberRepository.AddAsync(entity); result = !entity.IsNullOrDefault(); + if (result) + { + // + await SendPush( + action: XWebinarEntityHubAction.Subscribed.GetStringValue(), + payLoad: entity.ToJSON(), + connectionId: connectionId + ); + } // return result; @@ -822,10 +877,12 @@ namespace xWebinarService.Providers /// /// /// + /// /// public async Task Unsubscribe( Guid webinarId, - string subscriberId + string subscriberId, + string connectionId = null ) { // @@ -865,6 +922,15 @@ namespace xWebinarService.Providers ); entity = await WebinarSubscriberRepository.RemoveAsync(entity); result = !entity.IsNullOrDefault(); + if (result) + { + // + await SendPush( + action: XWebinarEntityHubAction.Unsubscribe.GetStringValue(), + payLoad: entity.ToJSON(), + connectionId: connectionId + ); + } // return result; @@ -1054,5 +1120,55 @@ namespace xWebinarService.Providers return result; } #endregion + + // + #region Hub Actions ... + /// + /// Send Custom Push Message ... + /// + /// + /// + /// + /// + public async Task SendPush( + string action, + string payLoad, + string connectionId = null + ) + { + // + var actions = new List + { + XBaseEntityHubAction.Add.GetStringValue(), + XBaseEntityHubAction.Update.GetStringValue(), + XBaseEntityHubAction.Delete.GetStringValue(), + XBaseEntityHubAction.AddMany.GetStringValue(), + XBaseEntityHubAction.DeleteMany.GetStringValue(), + XBaseEntityHubAction.UpdateMany.GetStringValue(), + XBaseEntityHubAction.AddOrUpdate.GetStringValue(), + XWebinarEntityHubAction.Subscribed.GetStringValue(), + XWebinarEntityHubAction.Unsubscribe.GetStringValue(), + }; + + // + // Validate ... + var isValid = + !Hub.IsNull() && + !action.IsNullOrEmpty() && + actions.Contains(action); + if (!isValid) + { + return; + } + + // + var clients = Hub.Clients.All; + if (!connectionId.IsNullOrEmpty()) + { + clients = Hub.Clients.AllExcept(connectionId); + } + await clients.SendAsync(action, payLoad, connectionId); + } + #endregion } } \ No newline at end of file