diff --git a/Base/XBaseHub.cs b/Base/XBaseHub.cs index a0dc57e..4cdfc89 100644 --- a/Base/XBaseHub.cs +++ b/Base/XBaseHub.cs @@ -1,404 +1,63 @@ using System; -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 xModels.Dtos; using xPushService.Constants; using xPushService.Interfaces; -using xPushService.Models; -namespace xPushService.Base { - /// - /// a base class for implementing Hubs ... - /// +namespace xPushService.Base +{ public abstract class XBaseHub : Hub, IXBaseHub { // #region Props ... - protected readonly IXPushGroupStore groupStore; - protected readonly IXPushConnectionStore connectionStore; + protected readonly ILogger logger; #endregion // #region Constructor ... public XBaseHub( - IXPushGroupStore groupStore, - IXPushConnectionStore connectionStore - ) : base() + ILogger logger + ) { - // - this.groupStore = groupStore; - this.connectionStore = connectionStore; + this.logger = logger; } #endregion - // - #region Abstract ... - public abstract XPushConnectionDto GetConnection(); - #endregion - - // - #region EnevtHandlers ... - #endregion - // #region Overrides ... - public override Task OnConnectedAsync() + public override async Task OnConnectedAsync() { // - var connection = GetConnection(); - if (!connection.IsNull()) + var connectionId = Context.ConnectionId; + if (!connectionId.IsNullOrEmpty()) { // - connectionStore - .Add(connection) - .RunTask(); - - // - var count = connectionStore - .Count() - .RunTask(); - - // - Console.WriteLine($"Count After Coonected: {count}"); + // Notify Other Clients Which a new Connection Joins ... + await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.NewConnection.GetStringValue(), connectionId); } // - return base.OnConnectedAsync(); + await base.OnConnectedAsync(); } - public override Task OnDisconnectedAsync(Exception exception) + public override async Task OnDisconnectedAsync(Exception exception) { // - var connection = GetConnection(); - if (!connection.IsNull()) + var connectionId = Context.ConnectionId; + if (!connectionId.IsNullOrEmpty()) { // - connectionStore - .RemoveByConnectionId(connection.Id) - .RunTask(); - - // - var count = connectionStore - .Count() - .RunTask(); - - // - Console.WriteLine($"Count After DisCoonected: {count}"); + // Notify Other Clients Which a Connection Closed ... + await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.ConnectionClosed.GetStringValue(), connectionId); } - - // - return base.OnDisconnectedAsync(exception); + await base.OnDisconnectedAsync(exception); } #endregion // - #region Actions ... - /// - /// Notify to all Other Clients which a new Connection is established ... - /// - /// - public Task NotifyNewConnection(string connectionId) - { - // - var actor = Context.User.Identity.Name; - var authType = Context.User.Identity.AuthenticationType; - var actorRole = Context?.User?.FindFirst("role")?.Value; - - // - var pushMessage = new XPushMessage - { - // - Actor = actor, - Payload = connectionId, - TimeStamp = DateTime.UtcNow, - Type = XPushType.System.GetStringValue(), - Topic = XPushType.System.GetStringValue(), - Action = XBasePushAction.NotifyNewConnection.GetStringValue(), - Message = $"a new connection stablished by {connectionId} ...", - }; - - // - Console.WriteLine($"XPushServiceLog => "); - Console.WriteLine($"XPushServiceLog => NotifyNewConnection: User: {actor}/Role: {actorRole}/AuthType: {authType}/ConnectionId: {connectionId}/ConnectedAt: {DateTime.UtcNow}"); - Console.WriteLine($"XPushServiceLog => "); - - // - return Clients.Others.SendAsync( - XBasePushAction.PushMessage.GetStringValue(), - pushMessage - ); - } - - /// - /// Update Last Seen ... - /// - public Task UpdateLastSeen() - { - var connectionId = Context.ConnectionId; - return connectionStore - .UpdateLastSeen(connectionId) - .ContinueWith(updateLastSeenTask => - { - // - var updateLastSeen = updateLastSeenTask - .RunTask(); - if (updateLastSeen) - { - // - var updatedConnection = connectionStore - .GetByConnectionId(connectionId) - .RunTask(); - - // - var count = connectionStore - .Count() - .RunTask(); - - // - Console.WriteLine($"Connection Last Seen Updated: {connectionId}: {updatedConnection.LastSeen}, Connection Count: {count} ..."); - } - }); - } - - /// - /// publicly Push a Message to Other Clients ... - /// - /// - /// - public Task PushMessageAsync(XPushMessage message) - { - // - if (message.IsNull()) - { - message = GetPushMessage(); - } - else - { - message.TimeStamp = DateTime.UtcNow; - } - - // - return Clients.Others.SendAsync(XBasePushAction.PushMessage.GetStringValue(), message); - } - - /// - /// publicly Push a Message to Other Clients ... - /// - /// - /// - [Authorize] - public Task AuthorizedMessageAsync(XPushMessage message) - { - // - if (message.IsNull()) - { - message = GetPushMessage(); - } - else - { - message.TimeStamp = DateTime.UtcNow; - } - - // - return Clients.Others.SendAsync(XBasePushAction.PushMessage.GetStringValue(), message); - } - - /// - /// push message to All connections ... - /// - /// - /// - public Task PushMessageToAll(XPushMessage message) - { - // - // Normalize Message ... - if (message.IsNull()) - { - message = GetPushMessage(); - } - else - { - message.TimeStamp = DateTime.UtcNow; - } - - // - return Clients - .All - .SendAsync( - XBasePushAction.PushMessage.GetStringValue(), - message - ); - } - - /// - /// push message to specific connection ... - /// - /// - /// - /// - public Task PushMessageToConnection( - string connectionId, - XPushMessage message - ) - { - // - // Validate Args ... - if (connectionId.IsNullOrEmpty()) - { - return Task.CompletedTask; - } - - // - // Normalize Message ... - if (message.IsNull()) - { - message = GetPushMessage(); - } - else - { - message.TimeStamp = DateTime.UtcNow; - } - - // - return Clients - .Client(connectionId) - .SendAsync( - XBasePushAction.PushMessage.GetStringValue(), - message - ); - } - - /// - /// push message to specific connections ... - /// - /// - /// - /// - public Task PushMessageToConnections( - IEnumerable connectionIds, - XPushMessage message - ) - { - // - // Validate Args ... - if (!connectionIds.HasChild()) - { - return Task.CompletedTask; - } - - // - // Normalize Message ... - if (message.IsNull()) - { - message = GetPushMessage(); - } - else - { - message.TimeStamp = DateTime.UtcNow; - } - - // - return Clients - .Clients( - connectionIds - .ToList() - .AsReadOnly() - ) - .SendAsync( - XBasePushAction.PushMessage.GetStringValue(), - message - ); - } - #endregion - - // - #region Protected ... - /// - /// retrieve connected user name ... - /// - /// - protected string GetUserName() - { - return Context?.User?.Identity?.Name; - } - - /// - /// retrieve connected user role ... - /// - /// - protected string GetUserRole() - { - return Context?.User?.FindFirst("role")?.Value; - } - - /// - /// Retrieve Empty Message ... - /// - /// - protected XPushMessage GetPushMessage() - { - // - var timeStamp = DateTime.UtcNow; - var actor = Context.User.Identity.Name; - var connectionId = Context.ConnectionId; - - // - var result = new XPushMessage - { - Actor = actor, - TimeStamp = timeStamp, - Payload = connectionId, - }; - - // - return result; - } - - /// - /// retrieve current connection id ... - /// - /// - protected string GetConnectionId() - { - return Context.ConnectionId; - } - - /// - /// Retrieve Connection Model from Context ... - /// - /// - protected XPushConnectionDto GetBaseConnection() - { - // - var connectionId = Context.ConnectionId; - var userName = Context.User.Identity.Name; - var authenticationType = Context.User.Identity.AuthenticationType; - - // - var httpContext = Context.GetHttpContext(); - var deviceJson = httpContext.Request.Query["Option"].ToString(); - var device = deviceJson.FromJSON(); - - // - var result = new XPushConnectionDto - { - User = userName, - Device = device, - Id = connectionId, - LastSeen = DateTime.UtcNow - }; - - // - return result; - } - #endregion - - // - #region Private ... + #region Actions ... #endregion } } \ No newline at end of file diff --git a/Base/XBaseHubClient.cs b/Base/XBaseHubClient.cs deleted file mode 100644 index 6e999ae..0000000 --- a/Base/XBaseHubClient.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Reactive.Subjects; -using Microsoft.AspNetCore.SignalR.Client; -using xPushService.Configurations; -using xPushService.Models; -using xPushService.Policies; - -namespace xPushService.Base { - // TODO: Complete this ... - public class XBaseHubClient { - // - #region Props ... - // - // private string CONNECTION_ID; - // private HubConnection HUB_CONNECTION; - // private IDisposable INTERVAL_SUBSCRIPTION; - // private XPushServiceConnectionRetryPolicy HUB_CONNECTION_POLICY; - - // - public Subject MessageReceived = new Subject (); - public Subject UserMessageReceived = new Subject (); - public Subject SystemMessageReceived = new Subject (); - - // - public Subject OnClose = new Subject (); - public Subject OnReconnected = new Subject (); - public Subject OnReconnecting = new Subject (); - - /// - /// readonly connection id ... - /// - /// - // public string ConnectionId { - // get { - // return this.CONNECTION_ID; - // } - // } - - /// - /// readonly connection object ... - /// - /// - // public HubConnection Connection { - // get { - // return this.HUB_CONNECTION; - // } - // } - #endregion - - // - #region Constructor ... - public XBaseHubClient ( - XPushServiceConfiguration config - ) { - - } - #endregion - - // - #region Abstract ... - #endregion - - // - #region Protected ... - #endregion - - // - #region Actions ... - #endregion - - // - #region IXAuthorizedPushActions ... - #endregion - - // - #region IXUserPushActions ... - #endregion - - // - #region IXGroupsPushActions ... - #endregion - - // - #region Private ... - #endregion - } -} \ No newline at end of file diff --git a/Base/XBaseWebRTCHub.cs b/Base/XBaseWebRTCHub.cs index 7da98c9..c0e432f 100644 --- a/Base/XBaseWebRTCHub.cs +++ b/Base/XBaseWebRTCHub.cs @@ -1,834 +1,66 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR; -using xCommons.Extensions; -using xExceptions.Constants; -using xModels.Dtos; -using xPushService.Constants; -using xPushService.Extensions; +using Microsoft.Extensions.Logging; using xPushService.Interfaces; -using xPushService.Models; +using Microsoft.AspNetCore.SignalR; +using xPushService.Constants; +using xCommons.Extensions; -namespace xPushService.Base { - public abstract class XBaseWebRTCHub : XBaseHub { +namespace xPushService.Base +{ + public abstract class XBaseWebRTCHub : XBaseHub, IXBaseWebRTCHub + { // #region Props ... - protected readonly IXWebRTCConnectionStore webRTCConnectionStore; #endregion // #region Constructor ... - public XBaseWebRTCHub ( - IXPushGroupStore groupStore, - IXPushConnectionStore connectionStore, - IXWebRTCConnectionStore webRTCConnectionStore - ) : base (groupStore, connectionStore) { - this.webRTCConnectionStore = webRTCConnectionStore; - } + protected XBaseWebRTCHub( + ILogger logger + ) : base(logger) + { } #endregion // - #region Overrides ... - public override Task OnConnectedAsync () { - return base.OnConnectedAsync (); - } - - public override Task OnDisconnectedAsync (Exception exception) { - // // - // var connectionId = GetConnectionId (); - - // // - // // Find Connections Active Calls ... - // var activeConnections = webRTCConnectionStore - // .FindMany (c => c.CallerConnectionId - // .ToNormalString () == connectionId - // .ToNormalString () || - // c.IsInCallees (connectionId) - // ) - // .RunTask (); - - // // - // if (activeConnections.HasChild ()) { - // activeConnections - // .ToList () - // .ForEach (c => { - // // - // CancelCall ( - // cancellerConnectionId: connectionId, - // reason: XCallEndReason.Disconnected, - // request: c - // ) - // .RunTask (); - // }); - // } - - // - return base.OnDisconnectedAsync (exception); - } - #endregion - - // - #region Actions ... + #region WebRTCActions ... /// - /// Send PreOffer Call Request ... + /// Sending WebRTC Offer To Specified Connection ... /// - /// - /// - /// + /// + /// /// - public Task RequestCall ( - XCallType type, - string connectionId, - XDeviceDto device - ) { - // - // Validate Args ... - if (type == XCallType.None || connectionId.IsNullOrEmpty ()) { - return Task.FromResult (false); - } - - // - // Check Connection Exists ... - var isConnectionExists = connectionStore - .IsExistsConnectionId (connectionId) - .RunTask (); - if (!isConnectionExists) { - return Task.FromResult (false); - } - - // - // retrieve connection object ... - var request = GetWebRTCConnection ( - calleeDevice: device, - connectionType: type, - calleeConnectionId: connectionId - ) - .RunTask (); - - // - // Add Connection to Store ... - AddOrUpdateWebRTCConnection (request) - .RunTask (); - - // - try { - // - Clients - .Clients ( - request - .GetReceivers () - ) - .SendAsync ( - XWebRTCAction.RequestCall.GetStringValue (), - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { } - - // - return Task.FromResult (false); + public async Task Offer(string offer, string to) + { + await Clients.Client(to).SendAsync(XWebRTCAction.Offer.GetStringValue(), offer); } /// - /// Send PreOffer Call Request ... + /// Sending WebRTC Answer to Specified Connection ... /// - /// - /// - /// + /// /// - public Task RequestUserCall ( - XCallType type, - string user, - XDeviceDto device - ) { - // - // Validate Args ... - if (type == XCallType.None || user.IsNullOrEmpty ()) { - return Task.FromResult (false); - } - - // - // Check Connection Exists ... - var isConnectionExists = connectionStore - .IsExistsUser (user) - .RunTask (); - if (!isConnectionExists) { - return Task.FromResult (false); - } - - // - // retrieve connection object ... - var request = GetUserWebRTCConnection ( - calleeDevice: device, - connectionType: type, - calleeUser: user - ) - .RunTask (); - - // - // Add Connection to Store ... - AddOrUpdateWebRTCConnection (request) - .RunTask (); - - // - try { - // - Clients - .Clients ( - request - .GetReceivers () - ) - .SendAsync ( - XWebRTCAction.RequestCall.GetStringValue (), - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { } - - // - return Task.FromResult (false); + public async Task Answer(string answer) + { + await Clients.All.SendAsync(XWebRTCAction.Answer.GetStringValue(), answer, Context.ConnectionId); } /// - /// Cancel or End Requested Call ... + /// Sending WebRTC Candidate to Specified Connecton ... /// + /// + /// /// - public Task CancelCall ( - string cancellerConnectionId, - XCallEndReason reason, - XWebRTCConnectionDto request) { + public async Task Candidate(string candidate, string to) + { // - // Validate Args ... - var isValid = IsWebRTCConnectionsExists (request) - .RunTask (); - if (!isValid) { - return Task.FromResult (false); + string actionName = XWebRTCAction.Candidate.GetStringValue(); + if (!string.IsNullOrEmpty(to)) + { + await Clients.Client(to).SendAsync(actionName, candidate, Context.ConnectionId); } - - // - // Check if i am Caller ... - var isCancellerCaller = request - .IsCaller (cancellerConnectionId); - var isCancellerInCallees = request - .IsInCallees (cancellerConnectionId); - - // - if (isCancellerCaller) { - // - request.Callees.ToList ().ForEach (callee => { - // - callee.EndReason = reason; - callee.EndTime = DateTime.UtcNow; - }); - - // - // Remove Connection From Store ... - webRTCConnectionStore - .Remove (request) - .RunTask (); - } else if (isCancellerInCallees) { - // - var canceller = request.GetCallee (cancellerConnectionId); - if (canceller.IsNull ()) { - return Task.FromResult (false); - } - - // - var updatedCanceller = canceller; - updatedCanceller.EndReason = reason; - updatedCanceller.EndTime = DateTime.UtcNow; - - // - request.Callees = request.Callees - .Update (canceller, updatedCanceller); - - // - // Remove connection from Store if all callees end calls ... - var canRemoveConnection = request.Callees.All (c => !c.EndTime.IsNull () && !c.EndReason.IsNull ()); - if (canRemoveConnection) { - webRTCConnectionStore - .Remove (request) - .RunTask (); - } else { - webRTCConnectionStore - .Update (request) - .RunTask (); - } - } - - // - try { - // - Clients - .Clients ( - request.GetReceivers () - ) - .SendAsync ( - XWebRTCAction.CancelCall.GetStringValue (), - request - ); - - // - return Task.FromResult (true); - } catch { - return Task.FromResult (false); - } - } - - /// - /// end a call request ... - /// - /// - /// - public Task RejectCall ( - string rejecterConnectionId, - XWebRTCConnectionDto request - ) { - // - // Validate Args ... - var isValid = IsWebRTCConnectionsExists (request) - .RunTask (); - var isRejecterInCallees = request - .IsInCallees (rejecterConnectionId); - if (!isValid || - !isRejecterInCallees || - rejecterConnectionId.IsNullOrEmpty () - ) { - return Task.FromResult (false); - } - - // - // Find Rejecter and Push Reject to it ... - var rejecter = request - .GetCallee (rejecterConnectionId); - if (rejecter.IsNull ()) { - return Task.FromResult (false); - } - - // - // Update request Callees ... - var updatedRejecter = rejecter; - updatedRejecter.EndTime = DateTime.UtcNow; - updatedRejecter.EndReason = XCallEndReason.Reject; - request.Callees = request.Callees - .Update (rejecter, updatedRejecter); - - // - // Check if Only one Callee and he Reject, Remove connection From Store, - // otherwise Update connection ... - var canRemoveConnection = request - .Callees.Count () == 1 && request.Callees - .All (c => c.ConnectionId - .ToNormalString () == rejecterConnectionId - .ToNormalString () - ); - if (canRemoveConnection) { - webRTCConnectionStore - .Remove (request) - .RunTask (); - } - - // - // Prepare Receivers ... - var receivers = new List () { - request.CallerConnectionId, - rejecterConnectionId - } - .AsReadOnly (); - - // - try { - // - Clients - .Clients (receivers) - .SendAsync ( - XWebRTCAction.RejectCall.GetStringValue (), - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { } - - // - return Task.FromResult (false); - } - - /// - /// answer a call request ... - /// - /// - /// - public Task AcceptCall ( - string accepterConnectionId, - XWebRTCConnectionDto request - ) { - // - // Validate Args ... - var isValid = IsWebRTCConnectionsExists (request) - .RunTask (); - var isAccepterInCallees = request - .IsInCallees (accepterConnectionId); - if (!isValid || - !isAccepterInCallees || - accepterConnectionId.IsNullOrEmpty () - ) { - return Task.FromResult (false); - } - - // - // Add Or Update ... - AddOrUpdateWebRTCConnection (request) - .RunTask (); - - // - // prepare recievers ... - var receivers = new List () { - request.CallerConnectionId, - accepterConnectionId, - } - .AsReadOnly (); - - // - try { - // - Clients - .Clients (receivers) - .SendAsync ( - XWebRTCAction.AcceptCall.GetStringValue (), - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { - return Task.FromResult (false); - } - } - #endregion - - // - #region WebRTC Signaling ... - /// - /// Send WebRTC Offer ... - /// - /// - /// - /// - public Task WebRTCOffer ( - XWebRTCSignalDto signal, - XWebRTCConnectionDto request - ) { - // - if ( - signal.IsNull () || - signal.Offer.IsNull () || - !IsValidWebRTCConnection (request) - ) { - return Task.FromResult (false); - } - - // - var connectionId = GetConnectionId (); - var offerRecievers = request - .GetReceivers () - .Where (r => r.ToNormalString () != connectionId.ToNormalString ()) - .ToList () - .AsReadOnly (); - - // - try { - // - Clients - .Clients (offerRecievers) - .SendAsync ( - XWebRTCAction.WebRTCOffer.GetStringValue (), - signal, - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { - return Task.FromResult (false); - } - } - - /// - /// Send WebRTC Answer ... - /// - /// - /// - /// - public Task WebRTCAnswer ( - XWebRTCSignalDto signal, - XWebRTCConnectionDto request - ) { - // - if ( - signal.IsNull () || - signal.Offer.IsNull () || - signal.Answer.IsNull () || - !IsValidWebRTCConnection (request) - ) { - return Task.FromResult (false); - } - - // - var connectionId = GetConnectionId (); - var answerRecievers = request - .GetReceivers () - .Where (r => r.ToNormalString () != connectionId.ToNormalString ()) - .ToList () - .AsReadOnly (); - - // - try { - // - Clients - .Clients (answerRecievers) - .SendAsync ( - XWebRTCAction.WebRTCAnswer.GetStringValue (), - signal, - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { - return Task.FromResult (false); - } - } - - /// - /// Send WebRTC ICE Candidates ... - /// - /// - /// - /// - public Task WebRTCICECandidate ( - XWebRTCSignalDto signal, - XWebRTCConnectionDto request - ) { - // - if ( - signal.IsNull () || - signal.Offer.IsNull () || - signal.Answer.IsNull () || - !signal.Cadidates.HasChild () || - !IsValidWebRTCConnection (request) - ) { - return Task.FromResult (false); - } - - // - var connectionId = GetConnectionId (); - var candidatesRecievers = request - .GetReceivers () - .Where (r => r.ToNormalString () != connectionId.ToNormalString ()) - .ToList () - .AsReadOnly (); - - // - try { - // - Clients - .Clients (candidatesRecievers) - .SendAsync ( - XWebRTCAction.WebRTCICECandidate.GetStringValue (), - signal, - request - ) - .RunTask (); - - // - return Task.FromResult (true); - } catch { - return Task.FromResult (false); - } - } - #endregion - - // - #region Protected ... - /// - /// create first time WebRTC connection by user name ... - /// - /// - /// - /// - /// - protected Task GetUserWebRTCConnection ( - XCallType connectionType, - string calleeUser, - XDeviceDto calleeDevice - ) { - // - // Validate Args ... - if ( - calleeDevice.IsNull () || - connectionType == XCallType.None || - calleeUser.IsNullOrEmpty () - ) { - throw XException.InvalidArgs.ToException (); - } - - // - var id = Guid.NewGuid ().ToString (); - - // - var httpContext = Context.GetHttpContext (); - var deviceJson = httpContext.Request.Query["Option"].ToString (); - - // - // Retrieve Caller Info ... - var callerConnectionId = Context.ConnectionId; - var callerUserName = Context?.User?.Identity?.Name; - var callerDevice = deviceJson.FromJSON (); - - // - // Retrieve Connection ... - var calleeConnection = connectionStore - .FindOne (c => c.User.ToNormalString () == calleeUser.ToNormalString ()) - .RunTask (); - - // - var result = new XWebRTCConnectionDto { - // - Id = id, - // - Payload = null, - Type = connectionType, - // - RequestTime = DateTime.UtcNow, - // - CallerUser = callerUserName, - CallerDevice = callerDevice, - CallerConnectionId = callerConnectionId, - // - Callees = new List { - new XWebRTCCalleeDto { - Device = calleeDevice, - User = calleeConnection.User, - ConnectionId = calleeConnection.Id, - } - } - }; - - // - return Task.FromResult (result); - } - - /// - /// create first time WebRTC connection ... - /// - /// - /// - /// - /// - protected Task GetWebRTCConnection ( - XCallType connectionType, - string calleeConnectionId, - XDeviceDto calleeDevice - ) { - // - // Validate Args ... - if ( - calleeDevice.IsNull () || - connectionType == XCallType.None || - calleeConnectionId.IsNullOrEmpty () - ) { - throw XException.InvalidArgs.ToException (); - } - - // - var id = Guid.NewGuid ().ToString (); - - // - var httpContext = Context.GetHttpContext (); - var deviceJson = httpContext.Request.Query["Option"].ToString (); - - // - // Retrieve Caller Info ... - var callerConnectionId = Context.ConnectionId; - var callerUserName = Context?.User?.Identity?.Name; - var callerDevice = deviceJson.FromJSON (); - - // - // Retrieve Connection ... - var calleeConnection = connectionStore - .GetByConnectionId (calleeConnectionId) - .RunTask (); - - // - var result = new XWebRTCConnectionDto { - // - Id = id, - // - Payload = null, - Type = connectionType, - // - RequestTime = DateTime.UtcNow, - // - CallerUser = callerUserName, - CallerDevice = callerDevice, - CallerConnectionId = callerConnectionId, - // - Callees = new List { - new XWebRTCCalleeDto { - Device = calleeDevice, - User = calleeConnection.User, - ConnectionId = calleeConnectionId, - } - } - }; - - // - return Task.FromResult (result); - } - - /// - /// Check i am caller or not ... - /// - /// - /// - protected bool AmICaller (XWebRTCConnectionDto request) { - // - // Validate Args ... - if (!request.IsValid () || - !IsValidWebRTCConnection (request) - ) { - throw XException.InvalidArgs.ToException (); - } - - // - var result = request.IsCaller (GetConnectionId ()); - return result; - } - - /// - /// Check i am callee or not ... - /// - /// - /// - protected bool AmICallee (XWebRTCConnectionDto request) { - // - // Validate Args ... - if (!request.IsValid () || - !IsValidWebRTCConnection (request)) { - throw XException.InvalidArgs.ToException (); - } - - // - var result = request.IsInCallees (GetConnectionId ()); - return result; - } - - /// - /// validate a web rtc connection ... - /// - /// - /// - protected bool IsValidWebRTCConnection (XWebRTCConnectionDto request) { - // - // Validate Args ... - if ( - request.IsNull () || - !request.IsValid () || - !request.Callees.HasChild () || - request.Type == XCallType.None || - request.CallerConnectionId.IsNullOrEmpty () - ) { - return false; - } - - // - return true; - } - - /// - /// check bot Caller and Callee Connections Exists ... - /// - /// - /// - protected Task IsWebRTCConnectionsExists (XWebRTCConnectionDto request) { - // - // Validate Args ... - if (!IsValidWebRTCConnection (request)) { - return Task.FromResult (false); - } - - // - var isCallerConnectionExists = connectionStore - .IsExistsConnectionId (request.CallerConnectionId) - .RunTask (); - - // - var isCalleesConnectionExists = !request.Callees.HasChild () ? true : - Task.WhenAll (request.Callees.Select (callee => connectionStore - .IsExistsConnectionId (callee.ConnectionId))) - .ContinueWith (allTasks => { - // - var allResults = allTasks - .RunTask (); - - // - return allResults.All (r => r == true); - }) - .RunTask (); - - // - if (!isCallerConnectionExists || !isCalleesConnectionExists) { - return Task.FromResult (false); - } - - // - return Task.FromResult (true); - } - - /// - /// Add or Update a WebRTCConnection To/In Store ... - /// - /// - /// - protected Task AddOrUpdateWebRTCConnection (XWebRTCConnectionDto request) { - // - if (!request.IsValid () || - request.Id.IsNullOrEmpty () - ) { - return Task.FromResult (false); - } - - // - // Check Exists or not ... - var isWebRTCConnectionExists = webRTCConnectionStore - .IsExistsByKey (request.Id) - .RunTask (); - - // - // Act based on existance ... - if (!isWebRTCConnectionExists) { - return webRTCConnectionStore.Add (request); - } else { - // - var updated = webRTCConnectionStore.Update (request) - .RunTask (); - var isUpdate = !updated.IsNull (); - - // - return Task.FromResult (isUpdate); + else + { + await Clients.All.SendAsync(actionName, candidate, Context.ConnectionId); } } #endregion diff --git a/Configurations/XPushServiceConfiguration.cs b/Configurations/XPushServiceConfiguration.cs index c30c0e0..c5dac4c 100644 --- a/Configurations/XPushServiceConfiguration.cs +++ b/Configurations/XPushServiceConfiguration.cs @@ -6,24 +6,12 @@ namespace xPushService.Configurations { /// string public string BaseRoute { get; set; } - /// - /// main action of push messages ... - /// - /// - public string PushMessageAction { get; set; } - /// /// determines log level of signalR ... /// /// public object ConnectionLogLevel { get; set; } - /// - /// when a client connected it's going to update last seen of a client by this interval ... - /// - /// - public int UpdateLastSeenInterval { get; set; } - /// /// when client disconnected it's automatically try to reconnect, this /// determines max number of try to connect ... diff --git a/Constants/XCallEndReason.cs b/Constants/XCallEndReason.cs deleted file mode 100644 index 9fedb52..0000000 --- a/Constants/XCallEndReason.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace xPushService.Constants { - public enum XCallEndReason { - End, - Missed, - Reject, - Canceled, - Disconnected - } -} \ No newline at end of file diff --git a/Constants/XCallType.cs b/Constants/XCallType.cs deleted file mode 100644 index b642a49..0000000 --- a/Constants/XCallType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace xPushService.Constants { - public enum XCallType { - None, - Chat, - AudioCall, - VideoCall, - DesktopShare, - AudioConference, - VideoConference, - } -} \ No newline at end of file diff --git a/Constants/XPushAction.cs b/Constants/XPushAction.cs new file mode 100644 index 0000000..900b794 --- /dev/null +++ b/Constants/XPushAction.cs @@ -0,0 +1,34 @@ +using xExceptions.Attributes; + +namespace xPushService.Constants +{ + public enum XBaseHubAction + { + /// + /// new Connection Join ... + /// + [StringValue("NewConnection")] + NewConnection, + /// + /// an Exists Connection Closed ... + /// + [StringValue("ConnectionClosed")] + ConnectionClosed, + } + + /// + /// All Actions in WebRTC Hubs ... + /// + public enum XWebRTCAction + { + // + [StringValue("Offer")] + Offer, + + [StringValue("Answer")] + Answer, + + [StringValue("Candidate")] + Candidate, + } +} \ No newline at end of file diff --git a/Constants/XPushType.cs b/Constants/XPushType.cs deleted file mode 100644 index 587593a..0000000 --- a/Constants/XPushType.cs +++ /dev/null @@ -1,32 +0,0 @@ -using xExceptions.Attributes; - -namespace xPushService.Constants { - /// - /// Determines Push Notification Types - /// - public enum XPushType { - /// System Type Notifications Relate Only to System - [StringValue("system")] - System, - - /// User Specific Types Of Push Notifications - [StringValue("user")] - User - } - - /// - /// Base Push Actions ... - /// - public enum XBasePushAction { - [StringValue ("PushMessageAsync")] - PushMessage, - [StringValue ("UserMessageAsync")] - UserMessage, - [StringValue ("AdminMessageAsync")] - AdminMessage, - [StringValue("AuthorizedMessageAsync")] - AuthorizedMessage, - [StringValue("NotifyNewConnection")] - NotifyNewConnection - } -} \ No newline at end of file diff --git a/Constants/XWebRTCAction.cs b/Constants/XWebRTCAction.cs deleted file mode 100644 index ad0354d..0000000 --- a/Constants/XWebRTCAction.cs +++ /dev/null @@ -1,32 +0,0 @@ -using xExceptions.Attributes; - -namespace xPushService.Constants { - public enum XWebRTCAction { - // - [StringValue ("RequestCall")] - RequestCall, - - [StringValue ("RequestUserCall")] - RequestUserCall, - - // - [StringValue ("CancelCall")] - CancelCall, - - [StringValue ("RejectCall")] - RejectCall, - - [StringValue ("AcceptCall")] - AcceptCall, - - // - [StringValue ("WebRTCOffer")] - WebRTCOffer, - - [StringValue ("WebRTCAnswer")] - WebRTCAnswer, - - [StringValue ("WebRTCICECandidate")] - WebRTCICECandidate, - } -} \ No newline at end of file diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index abc31de..70c2d0f 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; @@ -15,9 +14,7 @@ using xExceptions.Constants; using xPushService.Configurations; using xPushService.Constants; using xPushService.Helpers; -using xPushService.Interfaces; using xPushService.Providers; -using xPushService.Store; namespace xPushService.DI { @@ -70,6 +67,7 @@ namespace xPushService.DI ServiceLifetime lifeTime = ServiceLifetime.Singleton ) { + // AddPushService( services, config.GetXPushServiceConfiguration(), @@ -88,6 +86,7 @@ namespace xPushService.DI ServiceLifetime lifeTime = ServiceLifetime.Singleton ) { + // AddPushService( services, config, @@ -159,7 +158,7 @@ namespace xPushService.DI helper.GetHubs().ForEach(hubDescriptor => { // - var hubRoute = config.BaseRoute + "/" + hubDescriptor.Route; // Path.Combine (config.BaseRoute, hubDescriptor.Route); + var hubRoute = config.BaseRoute + "/" + hubDescriptor.Route; hubRoutes.Add(hubRoute); Console.WriteLine($"XPushService HubRoute: {hubRoute}"); @@ -253,42 +252,6 @@ namespace xPushService.DI // Register XPushService Configuration ... services.AddSingleton(config); - // - #region Try to Register Stores ... - // - var groupStore = services.GetRegisteredService(); - if (groupStore.IsNull()) - { - // - Log($"there is no provided PushGroupStore, try to register XPushGroupInMemoryStore ..."); - var storeEvents = services.GetRegisteredService(); - groupStore = new XPushGroupInMemoryStore(storeEvents); - services.AddSingleton(groupStore); - } - - // - var connectionStore = services.GetRegisteredService(); - if (connectionStore.IsNull()) - { - // - Log($"there is no provided XPushConnectionStore, try to register XPushConnectionInMemoryStore ..."); - var storeEvents = services.GetRegisteredService(); - connectionStore = new XPushConnectionInMemoryStore(storeEvents); - services.AddSingleton(connectionStore); - } - - // - var webRtcConnectionStore = services.GetRegisteredService(); - if (webRtcConnectionStore.IsNull()) - { - // - Log($"there is no provided XWebRTCConnectionStore, try to register XWebRTCConnectionInMemoryStore ..."); - var storeEvents = services.GetRegisteredService(); - webRtcConnectionStore = new XWebRTCConnectionInMemoryStore(storeEvents); - services.AddSingleton(webRtcConnectionStore); - } - #endregion - // // Register SignalR ... var builder = services.AddSignalR(); diff --git a/Events/XPushConnectionStoreEvents.cs b/Events/XPushConnectionStoreEvents.cs deleted file mode 100644 index a56404e..0000000 --- a/Events/XPushConnectionStoreEvents.cs +++ /dev/null @@ -1,9 +0,0 @@ -using xModels.Base; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Events -{ - public class XPushConnectionStoreEvents : XBaseStoreEvent, IXPushConnectionStoreEvents - { } -} \ No newline at end of file diff --git a/Events/XPushGroupStoreEvents.cs b/Events/XPushGroupStoreEvents.cs deleted file mode 100644 index a00ad81..0000000 --- a/Events/XPushGroupStoreEvents.cs +++ /dev/null @@ -1,9 +0,0 @@ -using xModels.Base; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Events -{ - public class XPushGroupStoreEvents : XBaseStoreEvent, IXPushGroupStoreEvents - { } -} \ No newline at end of file diff --git a/Events/XWebRTCConnectionStoreEvents.cs b/Events/XWebRTCConnectionStoreEvents.cs deleted file mode 100644 index 8a1ea21..0000000 --- a/Events/XWebRTCConnectionStoreEvents.cs +++ /dev/null @@ -1,9 +0,0 @@ -using xModels.Base; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Events -{ - public class XWebRTCConnectionStoreEvents : XBaseStoreEvent, IXWebRTCConnectionStoreEvents - { } -} \ No newline at end of file diff --git a/Extensions/ClaimsPrincipalExtensions.cs b/Extensions/ClaimsPrincipalExtensions.cs new file mode 100644 index 0000000..c48a042 --- /dev/null +++ b/Extensions/ClaimsPrincipalExtensions.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.SignalR; +using xCommons.Constants; +using xCommons.Extensions; +using xCommons.Helpers; +using xIdentityModels.Constants; +using xPushService.Models; + +namespace xPushService.Extensions +{ + public static class ClaimsPrincipalExtensions + { + /// + /// Generate User Info based on HubCallerContext ... + /// + /// + /// + public static XHubUserInfo GetUserInfo(this HubCallerContext source) + { + // + XHubUserInfo result = null; + + // + if (source.IsNull() || source.User.IsNull() || !source.User.Claims.HasChild()) + { + return result; + } + + // + result = new XHubUserInfo + { + UserId = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "", + UserName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "", + FirstName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "", + LastName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.LastName)?.Value ?? "", + Picture = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Picture)?.Value ?? "", + Email = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null, + PhoneNumber = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null, + }; + + // + #region Handle Gender ... + var genders = ObjectHelper.ToEnumerableKeys(); + var genderStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null; + if (genderStr.IsNullOrEmpty()) + { + result.Gender = XGender.Male; + } + else + { + result.Gender = genderStr.GetValue(); + } + #endregion + + // + #region Handle IsBanned ... + var isBannedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null; + if (isBannedStr.IsNullOrEmpty()) + { + result.IsBanned = false; + } + else + { + // + var isBanned = false; + Boolean.TryParse(isBannedStr, out isBanned); + + // + result.IsBanned = isBanned; + } + #endregion + + // + #region Handle IsEnabled ... + var isEnabledStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null; + if (isEnabledStr.IsNullOrEmpty()) + { + result.IsEnabled = false; + } + else + { + // + var isEnabled = false; + Boolean.TryParse(isEnabledStr, out isEnabled); + + // + result.IsEnabled = isEnabled; + } + #endregion + + // + #region Handle Email Confirmed ... + var emailConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null; + if (emailConfirmedStr.IsNullOrEmpty()) + { + result.EmailConfirmed = false; + } + else + { + // + var emailConfirmed = false; + Boolean.TryParse(emailConfirmedStr, out emailConfirmed); + + // + result.EmailConfirmed = emailConfirmed; + } + #endregion + + // + #region Handle PhoneNumber Confirmed ... + var phoneNumberConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null; + if (phoneNumberConfirmedStr.IsNullOrEmpty()) + { + result.PhoneNumberConfirmed = false; + } + else + { + // + var phoneNumberConfirmed = false; + Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed); + + // + result.PhoneNumberConfirmed = phoneNumberConfirmed; + } + #endregion + + // + #region Handle ExpiredOn ... + var expiredOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null; + if (expiredOnStr.IsNullOrEmpty()) + { + result.ExpiredOn = null; + } + else + { + // + long expiredOn = 0; + long.TryParse(expiredOnStr, out expiredOn); + + // + result.ExpiredOn = expiredOn; + } + #endregion + + // + #region Handle AuthenticatedOn ... + var authenticatedOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null; + if (authenticatedOnStr.IsNullOrEmpty()) + { + result.AuthenticatedOn = null; + } + else + { + // + long authenticatedOn = 0; + long.TryParse(authenticatedOnStr, out authenticatedOn); + + // + result.AuthenticatedOn = authenticatedOn; + } + #endregion + + // + #region Handle BrithDate ... + var brithDateStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? ""; + if (brithDateStr.IsNullOrEmpty()) + { + // BrithDate = null; + } + else + { + // + DateTime bDate; + DateTime.TryParse(brithDateStr, out bDate); + + // + result.BrithDate = bDate; + } + #endregion + + // + result.Issuers = source.User.Claims.Where(c => c.Type == XCustomClaims.Issuer)? + .Select(c => c.Value) ?? new HashSet(); + result.Audiences = source.User.Claims.Where(c => c.Type == XCustomClaims.Audience)? + .Select(c => c.Value) ?? new HashSet(); + result.ClientIds = source.User.Claims.Where(c => c.Type == XCustomClaims.ClientId)? + .Select(c => c.Value) ?? new HashSet(); + result.Scopes = source.User.Claims.Where(c => c.Type == XCustomClaims.Scope)? + .Select(c => c.Value) ?? new HashSet(); + result.Roles = source.User.Claims.Where(c => c.Type == XCustomClaims.Role)? + .Select(c => c.Value) ?? new HashSet(); + + // + return result; + } + } +} \ No newline at end of file diff --git a/Extensions/XWebRTCConnectionExtensions.cs b/Extensions/XWebRTCConnectionExtensions.cs deleted file mode 100644 index a335871..0000000 --- a/Extensions/XWebRTCConnectionExtensions.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using xCommons.Extensions; -using xPushService.Models; - -namespace xPushService.Extensions { - public static class XWebRTCConnectionExtensions { - /// - /// Validate Connection ... - /// - /// - /// - public static bool IsValid (this XWebRTCConnectionDto source) { - // - var result = false; - result = !source - .IsNull () && !source.CallerConnectionId - .IsNullOrEmpty () && ( - source.Callees - .HasChild () ? source.Callees - .All (callee => !callee.ConnectionId.IsNullOrDefault ()) : - true - ); - - // - return result; - } - - /// - /// Check a ConnectionId is Caller of a connection ... - /// - /// - /// - /// - public static bool IsCaller ( - this XWebRTCConnectionDto source, - string connectionId - ) { - // - var result = false; - - // - // Validate Args ... - if (!source.IsValid () || - connectionId.IsNullOrEmpty () - ) { - return result; - } - - // - result = connectionId - .ToNormalString () == source.CallerConnectionId - .ToNormalString (); - return result; - } - - /// - /// Check a ConnectionId is in Callees of a connection ... - /// - /// - /// - /// - public static bool IsInCallees ( - this XWebRTCConnectionDto source, - string connectionId - ) { - // - var result = false; - - // - // Validate Args ... - if (!source.IsValid () || - !source.Callees.HasChild () || - connectionId.IsNullOrEmpty () - ) { - return result; - } - - // - result = source.Callees.Any (callee => callee.ConnectionId - .ToNormalString () == connectionId - .ToNormalString ()); - - // - return result; - } - - /// - /// Get Receivers ... - /// - /// - /// - public static IReadOnlyList GetReceivers (this XWebRTCConnectionDto source) { - // - var result = new List (); - - // - // Validate Args ... - if (!source.IsValid ()) { - return result; - } - - // - // Add Caller ... - result.Add (source.CallerConnectionId); - - // - // Add Callees ... - source.Callees - .ToList () - .ForEach (callee => { - result.Add (callee.ConnectionId); - }); - - // - return result; - } - - /// - /// Retrieve Callee from Callees ... - /// - /// - /// - /// - public static XWebRTCCalleeDto GetCallee ( - this XWebRTCConnectionDto source, - string connectionId - ) { - // - // Validate Args ... - if (!source.IsValid () || - connectionId.IsNullOrEmpty () - ) { - return null; - } - - // - // Check Connection Id is In Callees or not ... - var isInCallees = source.IsInCallees (connectionId); - if (!isInCallees) { - return null; - } - - // - // retrieve result ... - var result = source.Callees - .FirstOrDefault (callee => callee.ConnectionId - .ToNormalString () == connectionId - .ToNormalString () - ); - - // - // return result ... - return result; - } - } -} \ No newline at end of file diff --git a/Interfaces/IXAuthorizedPushActions.cs b/Interfaces/IXAuthorizedPushActions.cs deleted file mode 100644 index e690982..0000000 --- a/Interfaces/IXAuthorizedPushActions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Threading.Tasks; -using xPushService.Models; - -namespace xPushService.Interfaces { - public interface IXAuthorizedPushActions { - /// - /// an authenticated user can push a message to others ... - /// - /// - /// - Task UserMessageAsync (XPushMessage message); - - /// - /// an admin user can push a message to others ... - /// - /// - /// - Task AdminMessageAsync (XPushMessage message); - } -} \ No newline at end of file diff --git a/Interfaces/IXBaseHub.cs b/Interfaces/IXBaseHub.cs index af941bb..5b467ab 100644 --- a/Interfaces/IXBaseHub.cs +++ b/Interfaces/IXBaseHub.cs @@ -1,27 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using xPushService.Models; - namespace xPushService.Interfaces { public interface IXBaseHub - { - Task OnConnectedAsync(); - Task OnDisconnectedAsync(Exception exception); - Task NotifyNewConnection(string connectionId); - Task UpdateLastSeen(); - Task PushMessageAsync(XPushMessage message); - Task AuthorizedMessageAsync(XPushMessage message); - Task PushMessageToAll(XPushMessage message); - Task PushMessageToConnection( - string connectionId, - XPushMessage message - ); - Task PushMessageToConnections( - IEnumerable connectionIds, - XPushMessage message - ); - } + { } } \ No newline at end of file diff --git a/Interfaces/IXBaseWebRTCHub.cs b/Interfaces/IXBaseWebRTCHub.cs new file mode 100644 index 0000000..8213a9e --- /dev/null +++ b/Interfaces/IXBaseWebRTCHub.cs @@ -0,0 +1,5 @@ +namespace xPushService.Interfaces +{ + public interface IXBaseWebRTCHub : IXBaseHub + {} +} \ No newline at end of file diff --git a/Interfaces/IXGroupsPushActions.cs b/Interfaces/IXGroupsPushActions.cs deleted file mode 100644 index ac5ceba..0000000 --- a/Interfaces/IXGroupsPushActions.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using xPushService.Models; - -namespace xPushService.Interfaces { - public interface IXGroupsPushActions { - /// - /// send a message to specific group ... - /// - /// - /// - /// - Task SendMessageToGroup ( - string groupName, - XPushMessage message - ); - - /// - /// send a message to specific groups ... - /// - /// - /// - /// - Task SendMessageToGroups ( - IEnumerable groupNames, - XPushMessage message - ); - - /// - /// add a connection to specific group ... - /// - /// - /// - /// - Task AddConnectionToGroup ( - string connectionId, - string groupName - ); - - /// - /// remove specific connection from a group ... - /// - /// - /// - /// - Task RemoveConnectionFromGroup ( - string connectionId, - string groupName - ); - - /// - /// retrieve all groups name ... - /// - /// - Task> GetGroupNames (); - - /// - /// retrieve all groups with it's connections ... - /// - /// - Task> GetGroups (); - - /// - /// remove all connections of specific group ... - /// - /// - /// - Task RemoveGroupConnections (string groupName); - - /// - /// retrieve all groups name for specific connection ... - /// - /// - /// - Task> GetConnectionGroups (string connectionId); - - /// - /// retrieve all connections in specific group ... - /// - /// - /// - Task> GetGroupConnections (string groupName); - } -} \ No newline at end of file diff --git a/Interfaces/IXPushConnectionStore.cs b/Interfaces/IXPushConnectionStore.cs deleted file mode 100644 index 1fe9405..0000000 --- a/Interfaces/IXPushConnectionStore.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using xModels.Dtos; -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces { - public interface IXPushConnectionStore : IXBaseStore { - // - #region Custom ... - /// - /// retrieve specific connection by it's Id ... - /// - /// - /// - Task GetByConnectionId (string connectionId); - - /// - /// retrieve specific user's connections ... - /// - /// - /// - Task> GetByUserName (string userName); - - /// - /// retrieve specific user's connected device connection - /// - /// - /// - /// - Task GetByUserDevice (string userName, XDeviceDto device); - - /// - /// check a connection exists or not by it's id ... - /// - /// - /// - Task IsExistsConnectionId (string connectionId); - - /// - /// check specific user connected or not ... - /// - /// - /// - Task IsExistsUser (string userName); - - /// - /// retrieve specific user's connected devices ... - /// - /// - /// - /// - Task> GetUserDevices (string userName); - - /// - /// remove specific connection by it's id ... - /// - /// - /// - Task RemoveByConnectionId (string connectionId); - - /// - /// remove specified user's connected device connection ... - /// - /// - /// - /// - Task RemoveByUserDevice (string userName, XDeviceDto device); - - /// - /// remove specific user's all connected devices ... - /// - /// - /// - Task RemoveUser (string userName); - - /// - /// Get specific connections last seen ... - /// - /// - /// - Task GetLastSeenByConnectionId (string connectionId); - - /// - /// get specific user's last seen ... - /// - /// - /// - Task GetLastSeenByUserName (string userName); - - /// - /// get specific user's connected device last seen ... - /// - /// - /// - /// - Task GetLastSeenByUserDevice (string userName, XDeviceDto device); - - /// - /// Update Connection last seen ... - /// - /// - /// - Task UpdateLastSeen(string connectionId); - #endregion - } -} \ No newline at end of file diff --git a/Interfaces/IXPushConnectionStoreEvents.cs b/Interfaces/IXPushConnectionStoreEvents.cs deleted file mode 100644 index 2b4cc39..0000000 --- a/Interfaces/IXPushConnectionStoreEvents.cs +++ /dev/null @@ -1,8 +0,0 @@ -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces -{ - public interface IXPushConnectionStoreEvents : IXBaseStoreEvents - { } -} \ No newline at end of file diff --git a/Interfaces/IXPushGroupStore.cs b/Interfaces/IXPushGroupStore.cs deleted file mode 100644 index 481db41..0000000 --- a/Interfaces/IXPushGroupStore.cs +++ /dev/null @@ -1,8 +0,0 @@ -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces -{ - public interface IXPushGroupStore : IXBaseStore - { } -} \ No newline at end of file diff --git a/Interfaces/IXPushGroupStoreEvents.cs b/Interfaces/IXPushGroupStoreEvents.cs deleted file mode 100644 index 0073d62..0000000 --- a/Interfaces/IXPushGroupStoreEvents.cs +++ /dev/null @@ -1,8 +0,0 @@ -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces -{ - public interface IXPushGroupStoreEvents : IXBaseStoreEvents - {} -} \ No newline at end of file diff --git a/Interfaces/IXPushProvider.cs b/Interfaces/IXPushProvider.cs deleted file mode 100644 index 9b3cbe7..0000000 --- a/Interfaces/IXPushProvider.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace xPushService.Interfaces -{ - public interface IXPushProvider - { - - } -} \ No newline at end of file diff --git a/Interfaces/IXUserPushActions.cs b/Interfaces/IXUserPushActions.cs deleted file mode 100644 index 1ce9f57..0000000 --- a/Interfaces/IXUserPushActions.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using xModels.Dtos; -using xPushService.Models; - -namespace xPushService.Interfaces { - public interface IXUserPushActions { - /// - /// add an specific user to a group ... - /// - /// - /// - /// - Task AddUserToGroup ( - string userName, - string groupName - ); - - /// - /// add an specific user's connected device to a group ... - /// - /// - /// - /// - /// - Task AddUserDeviceToGroup ( - string userName, - string groupName, - XDeviceDto device - ); - - /// - /// remove a user from specific groups ... - /// - /// - /// - /// - Task RemoveUserFromGroup ( - string userName, - string groupName - ); - - /// - /// remove specific user's connected device from a group ... - /// - /// - /// - /// - /// - Task RemoveUserDeviceFromGroup ( - string userName, - string groupName, - XDeviceDto device - ); - - /// - /// send a message to specific user ... - /// - /// - /// - /// - Task SendMessageToUser ( - string userName, - XPushMessage message - ); - - /// - /// send a message to a user's specific connected device ... - /// - /// - /// - /// - /// - Task SendMessageToUserDevice ( - string userName, - XPushMessage message, - XDeviceDto device - ); - - /// - /// send a message to specific users ... - /// - /// - /// - /// - Task SendMessageToUsers ( - IEnumerable userNames, - XPushMessage message - ); - - /// - /// retrieve all users groups ... - /// - /// - /// - Task> GetUserGroups (string userName); - - /// - /// retrieve specific user's connected device ... - /// - /// - /// - Task> GetUserConnections (string userName); - } -} \ No newline at end of file diff --git a/Interfaces/IXWebRTCConnectionStore.cs b/Interfaces/IXWebRTCConnectionStore.cs deleted file mode 100644 index 143932d..0000000 --- a/Interfaces/IXWebRTCConnectionStore.cs +++ /dev/null @@ -1,6 +0,0 @@ -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces { - public interface IXWebRTCConnectionStore : IXBaseStore { } -} \ No newline at end of file diff --git a/Interfaces/IXWebRTCConnectionStoreEvents.cs b/Interfaces/IXWebRTCConnectionStoreEvents.cs deleted file mode 100644 index cb64f18..0000000 --- a/Interfaces/IXWebRTCConnectionStoreEvents.cs +++ /dev/null @@ -1,8 +0,0 @@ -using xModels.Interfaces; -using xPushService.Models; - -namespace xPushService.Interfaces -{ - public interface IXWebRTCConnectionStoreEvents : IXBaseStoreEvents - { } -} \ No newline at end of file diff --git a/Models/XHubUserInfo.cs b/Models/XHubUserInfo.cs new file mode 100644 index 0000000..b6212d3 --- /dev/null +++ b/Models/XHubUserInfo.cs @@ -0,0 +1,34 @@ +using xModels.Base; +using xIdentityModels.Constants; +using System; +using System.Collections.Generic; + +namespace xPushService.Models +{ + public class XHubUserInfo : XBaseDto + { + // + #region Properties ... + public string UserId { get; set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Picture { get; set; } + public string Email { get; set; } + public string PhoneNumber { get; set; } + public XGender Gender { get; set; } + public bool IsBanned { get; set; } + public bool IsEnabled { get; set; } + public bool EmailConfirmed { get; set; } + public bool PhoneNumberConfirmed { get; set; } + public long? ExpiredOn { get; set; } + public long? AuthenticatedOn { get; set; } + public DateTime? BrithDate { get; set; } + public IEnumerable Issuers { get; set; } = new HashSet(); + public IEnumerable Audiences { get; set; } = new HashSet(); + public IEnumerable ClientIds { get; set; } = new HashSet(); + public IEnumerable Scopes { get; set; } = new HashSet(); + public IEnumerable Roles { get; set; } = new HashSet(); + #endregion + } +} \ No newline at end of file diff --git a/Models/XPushConnectionDto.cs b/Models/XPushConnectionDto.cs deleted file mode 100644 index 66d2eea..0000000 --- a/Models/XPushConnectionDto.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using xModels.Base; -using xModels.Dtos; - -namespace xPushService.Models { - /// - /// a Hub Connection ... - /// - public class XPushConnectionDto : XBaseStorableDto { - /// - /// Connection Id ... - /// - /// - public override string Id { get; set; } - /// - /// Connected User Name ... - /// - /// - public string User { get; set; } - /// - /// Connected Hub Type Name ... - /// - public string Type { get; set; } - /// - /// Connected User Device ... - /// - /// - public XDeviceDto Device { get; set; } - /// - /// Connected User's Last Seen ... - /// - /// - public DateTime LastSeen { get; set; } - } -} \ No newline at end of file diff --git a/Models/XPushGroupDto.cs b/Models/XPushGroupDto.cs deleted file mode 100644 index 7ed354e..0000000 --- a/Models/XPushGroupDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using xModels.Base; - -namespace xPushService.Models { - public class XPushGroupDto : XBaseStorableDto { - public override string Id { get; set; } - public List Connections { get; set; } - } -} \ No newline at end of file diff --git a/Models/XPushMessage.cs b/Models/XPushMessage.cs deleted file mode 100644 index 7437579..0000000 --- a/Models/XPushMessage.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; - -namespace xPushService.Models { - public class XPushMessage { - /// - /// Specify the Type of Push Notification ... - /// - /// - public string Type { get; set; } - - /// - /// Specify the Topic of PushNotification ... - /// NOTE: XPushTopic enum contains default Values and User can Extends it ... - /// - /// - public string Topic { get; set; } - - /// - /// Specify the Action Name by passing String Values ... - /// NOTE: XPushAction enum contains default Values for Actions ... - /// - /// - public string Action { get; set; } - - /// - /// if this is a User Push Action, we had to pass Actor ... - /// - /// - public string Actor { get; set; } - - /// - /// in CRUD actions or some Custom Actions, we can pass propper data - /// to clients ... - /// - /// - public string Payload { get; set; } - - /// - /// the message or additional Informations for passing to client ... - /// - /// - public string Message { get; set; } - - /// - /// Push notification date and time ... - /// - /// - public DateTime TimeStamp { get; set; } - } -} \ No newline at end of file diff --git a/Models/XWebRTCCalleeDto.cs b/Models/XWebRTCCalleeDto.cs deleted file mode 100644 index b881b9d..0000000 --- a/Models/XWebRTCCalleeDto.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using xModels.Base; -using xModels.Dtos; -using xPushService.Constants; - -namespace xPushService.Models { - public class XWebRTCCalleeDto : XBaseDto { - /// - /// Callee User Name ... - /// - /// - public string User { get; set; } - /// - /// Callee Device ... - /// - /// - public XDeviceDto Device { get; set; } - /// - /// Calee Connection Id ... - /// - /// - public string ConnectionId { get; set; } - /// - /// call end time ... - /// - /// - public DateTime EndTime { get; set; } - /// - /// call end reason ... - /// - /// - public XCallEndReason EndReason { get; set; } - } -} \ No newline at end of file diff --git a/Models/XWebRTCConnectionDto.cs b/Models/XWebRTCConnectionDto.cs deleted file mode 100644 index d2c5af5..0000000 --- a/Models/XWebRTCConnectionDto.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using xModels.Base; -using xModels.Dtos; -using xPushService.Constants; - -namespace xPushService.Models { - /// - /// describe a WebRTC Call ... - /// - public class XWebRTCConnectionDto : XBaseStorableDto { - public override string Id { get; set; } - /// - /// Call Type ... - /// - /// - public XCallType Type { get; set; } - /// - /// call request Time ... - /// - /// - public DateTime RequestTime { get; set; } - /// - /// Payload object ... - /// - /// - public object Payload { get; set; } - /// - /// Caller User Name ... - /// - /// - public string CallerUser { get; set; } - /// - /// Caller Device ... - /// - /// - public XDeviceDto CallerDevice { get; set; } - /// - /// Caller Connection Id ... - /// - /// - public string CallerConnectionId { get; set; } - /// - /// Callees Informations ... - /// - /// - public IEnumerable Callees { get; set; } - } -} \ No newline at end of file diff --git a/Models/XWebRTCSignalDto.cs b/Models/XWebRTCSignalDto.cs deleted file mode 100644 index 4f8b966..0000000 --- a/Models/XWebRTCSignalDto.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using xModels.Base; - -namespace xPushService.Models { - public class XWebRTCSignalDto : XBaseDto { - /// - /// Signalign Offer ... - /// - /// - public object Offer { get; set; } - /// - /// Signaling Answer ... - /// - /// - public object Answer { get; set; } - /// - /// Signaling Candidates - /// - /// - public IEnumerable Cadidates { get; set; } - } -} \ No newline at end of file diff --git a/Policies/XPushServiceConnectionRetryPolicy.cs b/Policies/XPushServiceConnectionRetryPolicy.cs deleted file mode 100644 index 94320e7..0000000 --- a/Policies/XPushServiceConnectionRetryPolicy.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using Microsoft.AspNetCore.SignalR.Client; -using xPushService.Configurations; - -namespace xPushService.Policies { - public class XPushServiceConnectionRetryPolicy : IRetryPolicy { - // - #region Props ... - // - Exception retryReason = null; - long previousRetryCount = 0; - TimeSpan elapsedMilliseconds; - - // - private readonly XPushServiceConfiguration config; - #endregion - - // - #region Constructor ... - public XPushServiceConnectionRetryPolicy ( - XPushServiceConfiguration config - ) { - this.config = config; - } - #endregion - - public TimeSpan? NextRetryDelay (RetryContext retryContext) { - // - this.retryReason = retryContext.RetryReason; - this.previousRetryCount = retryContext.PreviousRetryCount; - this.elapsedMilliseconds = retryContext.ElapsedTime; - - // - if (retryContext.PreviousRetryCount < config.PushConnectionMaxRetry) { - return TimeSpan.FromMilliseconds (this.config.PushConnectionReconnectDelay); - } else { - return null; - } - } - } -} \ No newline at end of file diff --git a/Providers/XPushProvider.cs b/Providers/XPushProvider.cs deleted file mode 100644 index c9b8879..0000000 --- a/Providers/XPushProvider.cs +++ /dev/null @@ -1,5 +0,0 @@ -using xPushService.Interfaces; - -namespace xPushService.Providers { - public class XPushProvider : IXPushProvider { } -} \ No newline at end of file diff --git a/Store/XPushConnectionInMemoryStore.cs b/Store/XPushConnectionInMemoryStore.cs deleted file mode 100644 index a031e87..0000000 --- a/Store/XPushConnectionInMemoryStore.cs +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using xCommons.Extensions; -using xExceptions.Constants; -using xModels.Base; -using xModels.Dtos; -using xModels.Providers; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Store -{ - public class XPushConnectionInMemoryStore : XBaseInMemoryStore, IXPushConnectionStore - { - // - #region Constructor ... - public XPushConnectionInMemoryStore( - IXPushConnectionStoreEvents events = null - ) : base(events) {} - #endregion - - // - #region Custom ... - /// - /// retrieve specific connection by it's Id ... - /// - /// - /// - public Task GetByConnectionId(string connectionId) - { - return Get(connectionId); - } - - /// - /// retrieve specific user's connections ... - /// - /// - /// - public Task> GetByUserName(string userName) - { - return FindMany(c => c.User.ToNormalString() == userName.ToNormalString()); - } - - /// - /// retrieve specific user's connected device connection - /// - /// - /// - /// - public Task GetByUserDevice(string userName, XDeviceDto device) - { - return FindOne(c => - c.User.ToNormalString() == userName.ToNormalString() && - c.Device.IsSameContent( - device, null, null, null, false - ) - ); - } - - /// - /// check a connection exists or not by it's id ... - /// - /// - /// - public Task IsExistsConnectionId(string connectionId) - { - return IsExistsByKey(connectionId); - } - - /// - /// check specific user connected or not ... - /// - /// - /// - public Task IsExistsUser(string userName) - { - return GetByUserName(userName) - .ContinueWith(findTask => - { - // - var findResult = findTask - .RunTask(); - - // - var result = findResult.Any(); - return result; - }); - } - - /// - /// retrieve specific user's connected devices ... - /// - /// - /// - /// - public Task> GetUserDevices(string userName) - { - return GetByUserName(userName) - .ContinueWith(userConnectionsTask => - { - // - var userConnections = userConnectionsTask - .RunTask(); - - // - var result = userConnections.Select(c => c.Device); - return result; - }); - } - - /// - /// remove specific connection by it's id ... - /// - /// - /// - public Task RemoveByConnectionId(string connectionId) - { - return RemoveByKey(connectionId); - } - - /// - /// remove specified user's connected device connection ... - /// - /// - /// - /// - public Task RemoveByUserDevice(string userName, XDeviceDto device) - { - return GetByUserDevice( - device: device, - userName: userName - ) - .ContinueWith(connectionTask => - { - // - var connection = connectionTask - .RunTask(); - - // - if (connection.IsNull()) - { - return false; - } - - // - var result = Remove(connection) - .RunTask(); - return result; - }); - } - - /// - /// remove specific user's all connected devices ... - /// - /// - /// - public Task RemoveUser(string userName) - { - return GetByUserName(userName) - .ContinueWith(connectionsTask => - { - // - var connections = connectionsTask - .RunTask(); - - // - if (!connections.HasChild()) - { - return false; - } - - // - var result = RemoveMany(new XBaseRangeRequest - { - Items = connections - }) - .RunTask(); - - // - return result; - }); - } - - /// - /// Get specific connections last seen ... - /// - /// - /// - public Task GetLastSeenByConnectionId(string connectionId) - { - return GetByConnectionId(connectionId) - .ContinueWith(connectionTask => - { - // - var connection = connectionTask - .RunTask(); - - // - if (connection.IsNull()) - { - throw XException.NotFound.ToException(); - } - - // - var result = connection.LastSeen; - return result; - }); - } - - /// - /// get specific user's last seen ... - /// - /// - /// - public Task GetLastSeenByUserName(string userName) - { - return GetByUserName(userName) - .ContinueWith(connectionsTask => - { - // - var connections = connectionsTask - .RunTask(); - - // - if (!connections.HasChild()) - { - throw XException.NotFound.ToException(); - } - - // - var result = connections - .Select(c => c.LastSeen) - .Max(); - - // - return result; - }); - } - - /// - /// get specific user's connected device last seen ... - /// - /// - /// - /// - public Task GetLastSeenByUserDevice(string userName, XDeviceDto device) - { - return GetByUserDevice( - device: device, - userName: userName - ) - .ContinueWith(connectionTask => - { - // - var connection = connectionTask - .RunTask(); - - // - if (connection.IsNull()) - { - throw XException.NotFound.ToException(); - } - - // - var result = connection.LastSeen; - return result; - }); - } - - /// - /// Update Connection last seen ... - /// - /// - /// - public Task UpdateLastSeen(string connectionId) - { - return IsExistsConnectionId(connectionId) - .ContinueWith(isExistsTask => - { - // - // define empty result ... - var result = false; - - // - // run task and get result ... - result = isExistsTask - .RunTask(); - - // - // check result is false ... - if (!result) - { - return result; - } - - // - // retreive connection ... - var connection = GetByConnectionId(connectionId) - .RunTask(); - result = !connection.IsNull(); - if (!result) - { - return result; - } - - // - // Update Connection last seen ... - connection.LastSeen = DateTime.UtcNow; - var updatedConnection = Update(connection) - .RunTask(); - result = !updatedConnection.IsNull(); - - // - return result; - }); - } - #endregion - } -} \ No newline at end of file diff --git a/Store/XPushGroupInMemoryStore.cs b/Store/XPushGroupInMemoryStore.cs deleted file mode 100644 index d1c3036..0000000 --- a/Store/XPushGroupInMemoryStore.cs +++ /dev/null @@ -1,16 +0,0 @@ -using xModels.Providers; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Store -{ - public class XPushGroupInMemoryStore : XBaseInMemoryStore, IXPushGroupStore - { - // - #region Constructor ... - public XPushGroupInMemoryStore( - IXPushGroupStoreEvents events = null - ) : base(events) { } - #endregion - } -} \ No newline at end of file diff --git a/Store/XWebRTCConnectionInMemoryStore.cs b/Store/XWebRTCConnectionInMemoryStore.cs deleted file mode 100644 index a02ad7f..0000000 --- a/Store/XWebRTCConnectionInMemoryStore.cs +++ /dev/null @@ -1,16 +0,0 @@ -using xModels.Providers; -using xPushService.Interfaces; -using xPushService.Models; - -namespace xPushService.Store -{ - public class XWebRTCConnectionInMemoryStore : XBaseInMemoryStore, IXWebRTCConnectionStore - { - // - #region Constructor ... - public XWebRTCConnectionInMemoryStore( - IXWebRTCConnectionStoreEvents events = null - ) : base(events) { } - #endregion - } -} \ No newline at end of file diff --git a/xPushService.csproj b/xPushService.csproj index 405bc2f..6ce86a9 100644 --- a/xPushService.csproj +++ b/xPushService.csproj @@ -28,6 +28,7 @@ +