Backup and Clean Push Service and implement new Structure of Push Service ...

This commit is contained in:
2025-11-14 16:40:45 +03:30
parent cfcb2d12b4
commit 3bd4b8d562
40 changed files with 333 additions and 2560 deletions
+20 -361
View File
@@ -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 {
/// <summary>
/// a base class for implementing Hubs ...
/// </summary>
namespace xPushService.Base
{
public abstract class XBaseHub : Hub, IXBaseHub
{
//
#region Props ...
protected readonly IXPushGroupStore groupStore;
protected readonly IXPushConnectionStore connectionStore;
protected readonly ILogger<XBaseHub> logger;
#endregion
//
#region Constructor ...
public XBaseHub(
IXPushGroupStore groupStore,
IXPushConnectionStore connectionStore
) : base()
ILogger<XBaseHub> 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 ...
/// <summary>
/// Notify to all Other Clients which a new Connection is established ...
/// </summary>
/// <param name="connectionId"></param>
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
);
}
/// <summary>
/// Update Last Seen ...
/// </summary>
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} ...");
}
});
}
/// <summary>
/// publicly Push a Message to Other Clients ...
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public Task PushMessageAsync(XPushMessage message)
{
//
if (message.IsNull())
{
message = GetPushMessage();
}
else
{
message.TimeStamp = DateTime.UtcNow;
}
//
return Clients.Others.SendAsync(XBasePushAction.PushMessage.GetStringValue(), message);
}
/// <summary>
/// publicly Push a Message to Other Clients ...
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
[Authorize]
public Task AuthorizedMessageAsync(XPushMessage message)
{
//
if (message.IsNull())
{
message = GetPushMessage();
}
else
{
message.TimeStamp = DateTime.UtcNow;
}
//
return Clients.Others.SendAsync(XBasePushAction.PushMessage.GetStringValue(), message);
}
/// <summary>
/// push message to All connections ...
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
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
);
}
/// <summary>
/// push message to specific connection ...
/// </summary>
/// <param name="connectionId"></param>
/// <param name="message"></param>
/// <returns></returns>
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
);
}
/// <summary>
/// push message to specific connections ...
/// </summary>
/// <param name="connectionIds"></param>
/// <param name="message"></param>
/// <returns></returns>
public Task PushMessageToConnections(
IEnumerable<string> 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 ...
/// <summary>
/// retrieve connected user name ...
/// </summary>
/// <returns></returns>
protected string GetUserName()
{
return Context?.User?.Identity?.Name;
}
/// <summary>
/// retrieve connected user role ...
/// </summary>
/// <returns></returns>
protected string GetUserRole()
{
return Context?.User?.FindFirst("role")?.Value;
}
/// <summary>
/// Retrieve Empty Message ...
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// retrieve current connection id ...
/// </summary>
/// <returns></returns>
protected string GetConnectionId()
{
return Context.ConnectionId;
}
/// <summary>
/// Retrieve Connection Model from Context ...
/// </summary>
/// <returns></returns>
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<XDeviceDto>();
//
var result = new XPushConnectionDto
{
User = userName,
Device = device,
Id = connectionId,
LastSeen = DateTime.UtcNow
};
//
return result;
}
#endregion
//
#region Private ...
#region Actions ...
#endregion
}
}