Files
xPushService/Base/XBaseHub.cs
T

363 lines
11 KiB
C#

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 {
/// <summary>
/// a base class for implementing Hubs ...
/// </summary>
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 ...
/// <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 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<XDeviceDto> ();
//
var result = new XPushConnectionDto {
User = userName,
Device = device,
Id = connectionId,
LastSeen = DateTime.UtcNow
};
//
return result;
}
#endregion
//
#region Private ...
#endregion
}
}