using System; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using xCommons.Extensions; using xExceptions.Constants; using xIdentityModels.Models; using xPushService.Base; using xPushService.Extensions; using xWebinarService.Constants; using xWebinarService.Models.Dtos; using xWebinarService.Providers; namespace xWebinarService.Hub { public class XWebinarHub : XBaseWebRTCHub { // #region Props ... public readonly XWebinarProvider webinarProvider; #endregion // #region Constructor ... public XWebinarHub( ILogger logger, XWebinarProvider webinarProvider ) : base(logger) { this.webinarProvider = webinarProvider; } #endregion // #region Actions ... /// /// a Webinar Owner Open Webinar for Broadcasting ... /// /// /// [Authorize] public async Task WebinarOpened(Guid webinarId) { // // Validate Arg ... var isValid = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!isValid) { // logger.LogError($"Invalid Webinar Provider ..."); return; } // // Reading and Validate Requirements ... var userInfo = Context.GetUserInfo(); var connectionId = Context.ConnectionId; isValid = !userInfo.IsNullOrDefault() && !connectionId.IsNullOrEmpty(); if (!isValid) { // logger.LogError($"Invaid User Info ..."); return; } // // Retrieve Webinar Model and Validate it Exists ... try { // // Retrieve Webinar ... var webinar = await webinarProvider.GetWebinar(webinarId); // // Validate Webinar ... isValid = !webinar.IsNullOrDefault(); if (!isValid) { // XException.NotFound.Throw(); logger.LogError($"Webinar Not Found ..."); } // // Validate User is Webinar Owner ... isValid = !userInfo.UserId.IsNullOrEmpty() && userInfo.UserId == webinar.OwnerId; if (!isValid) { // XException.NotAllowed.Throw(); logger.LogError($"Not Allowed to Present Webinar ..."); } // // Now try to Enable Webinar and Notify Webinars Client Which it's Open ... webinar.Enabled = true; webinar = await webinarProvider.UpdateWebinar(webinar); await Clients.AllExcept(connectionId).SendAsync(XWebinarHubAction.WebinarOpened.GetStringValue(), webinarId); // // Create a Group and Put User on it ... await Groups.AddToGroupAsync(connectionId, webinarId.ToString()); } catch { } } /// /// Close a Webinar by it's Owner ... /// /// /// [Authorize] public async Task WebinarClosed(Guid webinarId) { // // Validate Arg ... var isValid = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!isValid) { // logger.LogError($"Invalid Webinar Provider ..."); return; } // // Reading and Validate Requirements ... var userInfo = Context.GetUserInfo(); var connectionId = Context.ConnectionId; isValid = !userInfo.IsNullOrDefault() && !connectionId.IsNullOrEmpty(); if (!isValid) { // logger.LogError($"Invaid User Info ..."); return; } // // Retrieve Webinar Model and Validate it Exists ... try { // // Retrieve Webinar ... var webinar = await webinarProvider.GetWebinar(webinarId); // // Validate Webinar ... isValid = !webinar.IsNullOrDefault(); if (!isValid) { // XException.NotFound.Throw(); logger.LogError($"Webinar Not Found ..."); } // // Validate User is Webinar Owner ... isValid = !userInfo.UserId.IsNullOrEmpty() && userInfo.UserId == webinar.OwnerId; if (!isValid) { // XException.NotAllowed.Throw(); logger.LogError($"Not Allowed to Present Webinar ..."); } // // Now try to Enable Webinar and Notify Webinars Client Which it's Open ... webinar.Enabled = false; webinar = await webinarProvider.UpdateWebinar(webinar); await Clients.AllExcept(connectionId).SendAsync(XWebinarHubAction.WebinarClosed.GetStringValue(), webinarId); // var webinarName = webinarId.ToString(); await Clients.OthersInGroup(webinarName).SendAsync(XWebinarHubAction.WebinarClosed.ToString()); await Groups.RemoveFromGroupAsync(connectionId, webinarName); } catch { } } /// /// a Webinar Subscriber Joined to Opened Webinar ... /// /// /// [Authorize] public async Task ViewerJoined(Guid webinarId) { // // Validate ... var isValid = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!isValid) { // logger.LogError($"Invalid Webinar Provider ..."); return; } // // Retrieve requirements ... var userInfo = Context.GetUserInfo(); var connectionId = Context.ConnectionId; isValid = !userInfo.IsNullOrDefault() && !connectionId.IsNullOrEmpty(); if (!isValid) { // logger.LogError($"Invaid User Info ..."); return; } // try { // // Reading Webinar ... var webinar = await webinarProvider.GetWebinar(webinarId); isValid = !webinar.IsNullOrDefault(); if (!isValid) { // logger.LogError($"Webinar Not Found ..."); XException.NotFound.Throw(); } // // Validate User is Webinar Subscriber ... // Or Webinar is Open ... if (webinar.Type != XWebinarType.Public) { // isValid = await webinarProvider.IsSubscribed( webinarId: webinarId, subscriberId: userInfo.UserId ); if (!isValid) { // logger.LogError("User Not Have Permission to Join Webinar ..."); XException.NotAllowed.Throw(); } } // var webinarName = webinarId.ToString(); // // Add User to Webinar ... await Groups.AddToGroupAsync(connectionId, webinarName); // // Notify Other Users which a Viewer Joined ... await Clients.OthersInGroup(webinarName).SendAsync(XWebinarHubAction.ViewerJoined.GetStringValue(), connectionId, userInfo.UserId, userInfo.UserName); } catch { } } /// /// a Webina Subscriber Lefts Group ... /// /// /// [Authorize] public async Task ViewerLeaved(Guid webinarId) { // // Validate ... var isValid = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!isValid) { // logger.LogError($"Invalid Webinar Provider ..."); return; } // // Retrieve requirements ... var userInfo = Context.GetUserInfo(); var connectionId = Context.ConnectionId; isValid = !userInfo.IsNullOrDefault() && !connectionId.IsNullOrEmpty(); if (!isValid) { // logger.LogError($"Invaid User Info ..."); return; } // try { // // Reading Webinar ... var webinar = await webinarProvider.GetWebinar(webinarId); isValid = !webinar.IsNullOrDefault(); if (!isValid) { // logger.LogError($"Webinar Not Found ..."); XException.NotFound.Throw(); } // // Validate User is Webinar Subscriber ... // Or Webinar is Open ... if (webinar.Type != XWebinarType.Public) { // isValid = await webinarProvider.IsSubscribed( webinarId: webinarId, subscriberId: userInfo.UserId ); if (!isValid) { // logger.LogError("User Not Have Permission to Join Webinar ..."); XException.NotAllowed.Throw(); } } // var webinarName = webinarId.ToString(); // // Add User to Webinar ... await Groups.RemoveFromGroupAsync(connectionId, webinarName); // // Notify Other Users which a Viewer Leaved ... await Clients.OthersInGroup(webinarName).SendAsync(XWebinarHubAction.ViewerLeaved.GetStringValue(), connectionId, userInfo.UserId, userInfo.UserName ); } catch { } } /// /// Send a Message to Specified Webinar ... /// /// /// /// [Authorize] public async Task Message(Guid webinarId, string message) { // // Validate ... var isValid = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!isValid) { // logger.LogError($"Invalid Webinar Provider ..."); return; } // // Retrieve requirements ... var userInfo = Context.GetUserInfo(); var connectionId = Context.ConnectionId; isValid = !userInfo.IsNullOrDefault() && !connectionId.IsNullOrEmpty(); if (!isValid) { // logger.LogError($"Invaid User Info ..."); return; } // try { // // Reading Webinar ... var webinar = await webinarProvider.GetWebinar(webinarId); isValid = !webinar.IsNullOrDefault(); if (!isValid) { // logger.LogError($"Webinar Not Found ..."); XException.NotFound.Throw(); } // // Validate User is Webinar Owner or Subscriber ... // Or Webinar is Open ... if (webinar.Type != XWebinarType.Public) { // isValid = userInfo.UserId == webinar.OwnerId || (await webinarProvider.IsSubscribed( webinarId: webinarId, subscriberId: userInfo.UserId )); if (!isValid) { // logger.LogError("User Not Have Permission to Join Webinar ..."); XException.NotAllowed.Throw(); } } // var webinarName = webinarId.ToString(); // // Notify Other Users which a Viewer Leaved ... await Clients.OthersInGroup(webinarName).SendAsync(XWebinarHubAction.Message.GetStringValue(), connectionId, userInfo.UserId, userInfo.UserName, message ); } catch { } } #endregion } }