562 lines
19 KiB
C#
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
|
|
}
|
|
} |