Files
xWebinarService/Hubs/XWebinarHub.cs
T

562 lines
19 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xPushService.Base;
using xPushService.Extensions;
using xWebinarService.Constants;
using xWebinarService.Interfaces;
using xWebinarService.Models.Entities;
namespace xWebinarService.Hubs
{
public class XWebinarHub : XBaseWebRTCHub
{
//
#region Props ...
public readonly IXWebinarProvider webinarProvider;
private readonly IXWebinarGroupStore webinarGroupStore;
#endregion
//
#region Constructor ...
public XWebinarHub(
ILogger<XWebinarHub> logger,
IXWebinarProvider webinarProvider,
IXWebinarGroupStore webinarGroupStore
) : base(logger)
{
this.webinarProvider = webinarProvider;
this.webinarGroupStore = webinarGroupStore;
}
#endregion
//
#region Actions ...
/// <summary>
/// a Webinar Owner Open Webinar for Broadcasting ...
/// </summary>
/// <param name="webinarId"></param>
/// <returns></returns>
[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());
//
// Check Exists or not ...
var connection = new XHubConnectionDto
{
UserId = userInfo.UserId,
ConnectionId = connectionId,
Username = userInfo.UserName,
};
var groupEntity = await webinarGroupStore.FindOneAsync(x => x.WebinarId == webinarId);
if (!groupEntity.IsNullOrDefault())
{
//
// Update ...
groupEntity.Connections.Clear();
groupEntity.Connections.Add(connection);
await webinarGroupStore.UpdateAsync(groupEntity.Id, groupEntity);
}
else
{
//
// Add ...
groupEntity = new XWebinarGroupEntity
{
WebinarId = webinarId
};
groupEntity.Connections.Add(connection);
await webinarGroupStore.AddAsync(groupEntity);
}
}
catch { }
}
/// <summary>
/// Close a Webinar by it's Owner ...
/// </summary>
/// <param name="webinarId"></param>
/// <returns></returns>
[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);
//
// Check Exists or not ...
var groupEntity = await webinarGroupStore.FindOneAsync(x => x.WebinarId == webinarId);
if (!groupEntity.IsNullOrDefault())
{
await webinarGroupStore.RemoveAsync(groupEntity.Id);
}
}
catch { }
}
/// <summary>
/// a Webinar Subscriber Joined to Opened Webinar ...
/// </summary>
/// <param name="webinarId"></param>
/// <returns></returns>
[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,
webinarId,
userInfo.UserId,
userInfo.UserName
);
//
// Check Exists or not ...
var connection = new XHubConnectionDto
{
UserId = userInfo.UserId,
ConnectionId = connectionId,
Username = userInfo.UserName,
};
var groupEntity = await webinarGroupStore.FindOneAsync(x => x.WebinarId == webinarId);
if (!groupEntity.IsNullOrDefault())
{
//
// Check Current User ID Exists ...
var userConnection = groupEntity.Connections.FirstOrDefault(c => c.UserId == userInfo.UserId);
if (!userConnection.IsNullOrDefault())
{
userConnection.ConnectionId = connectionId;
}
else
{
groupEntity.Connections.Add(connection);
}
//
await webinarGroupStore.UpdateAsync(groupEntity.Id, groupEntity);
}
}
catch
{ }
}
/// <summary>
/// a Webina Subscriber Lefts Group ...
/// </summary>
/// <param name="webinarId"></param>
/// <returns></returns>
[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,
webinarId,
userInfo.UserId,
userInfo.UserName
);
//
// Check Exists or not ...
var groupEntity = await webinarGroupStore.FindOneAsync(x => x.WebinarId == webinarId);
if (!groupEntity.IsNullOrDefault())
{
//
// Check Current User ID Exists ...
var userConnection = groupEntity.Connections.FirstOrDefault(c => c.ConnectionId == connectionId);
if (!userConnection.IsNullOrDefault())
{
groupEntity.Connections.Remove(userConnection);
}
//
await webinarGroupStore.UpdateAsync(groupEntity.Id, groupEntity);
}
}
catch
{ }
}
/// <summary>
/// Return a Collection of Webinars Visitors ...
/// </summary>
/// <param name="webinarId"></param>
/// <returns></returns>
[Authorize]
public async Task<IEnumerable<XHubConnectionDto>> WebinarVisitors(Guid webinarId)
{
//
var result = new List<XHubConnectionDto>();
//
// Reading and Validate Requirements ...
var userInfo = Context.GetUserInfo();
var connectionId = Context.ConnectionId;
//
// Check Group Exists ...
var groupEntity = await webinarGroupStore.FindOneAsync(x => x.WebinarId == webinarId);
if (!groupEntity.IsNullOrDefault())
{
//
// Validate Requester is a Viewer ...
var connection = groupEntity.Connections.FirstOrDefault(c => c.ConnectionId == connectionId ||
c.UserId == userInfo.UserId
);
if (!connection.IsNullOrDefault())
{
result = groupEntity.Connections;
}
}
//
return result;
}
/// <summary>
/// Send a Message to Specified Webinar ...
/// </summary>
/// <param name="webinarId"></param>
/// <param name="message"></param>
/// <returns></returns>
[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
}
}