using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; using xCommons.Extensions; using xModels.Dtos; using xPushService.Constants; using xPushService.Interfaces; using xPushService.Models; namespace xPushService.Base { /// /// a base class for implementing Hubs ... /// public abstract class XBaseHub : Hub { // #region Props ... protected readonly IXPushGroupStore groupStore; protected readonly IXPushConnectionStore connectionStore; #endregion // #region Constructor ... public XBaseHub ( IXPushGroupStore groupStore, IXPushConnectionStore connectionStore ) : base () { // this.groupStore = groupStore; this.connectionStore = connectionStore; } #endregion // #region Abstract ... #endregion // #region EnevtHandlers ... #endregion // #region Overrides ... public override Task OnConnectedAsync () { // var connection = GetConnection (); if (!connection.IsNull ()) { // connectionStore .Add (connection) .RunTask (); // var count = connectionStore .Count () .RunTask (); // Console.WriteLine ($"Count After Coonected: {count}"); } // return base.OnConnectedAsync (); } public override Task OnDisconnectedAsync (Exception exception) { // var connection = GetConnection (); if (!connection.IsNull ()) { // connectionStore .RemoveByConnectionId (connection.Id) .RunTask (); // var count = connectionStore .Count () .RunTask (); // Console.WriteLine ($"Count After DisCoonected: {count}"); } // return 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, Type = XPushType.System, TimeStamp = DateTime.UtcNow, Topic = (int) XPushType.System, 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 GetConnection () { // 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 ... #endregion } }