2025-07-10 12:24:31 +03:30
2025-07-10 10:59:59 +03:30
2024-01-25 04:47:14 +03:30
2025-07-03 15:07:33 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2025-07-10 10:59:59 +03:30
2025-07-10 12:24:31 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30
2024-01-25 04:47:14 +03:30

xPushService

it is a Part of xDashboard Projects on SaherElm IT Center which provides all required models and actions in related to handling SignalR Push Platforms.

since this module used as a base infrastructure provider, you have to create a Helper Module based on it, for creating your projects requirements. we call it commonly xPushHelper.

xPushHelper

it is a simple xDashboard based module. which depends on these modules:

  • xCommons
  • xPushService

this is so important, if you protect your data using xIdentityServer. you need to add an additional refrence to your xIdentityHelper module.

  <!-- Local Modules -->
  <ItemGroup>
    <PackageReference Include="xDashboard.xCommons" Version="1.0.0" />
    <PackageReference Include="xDashboard.xPushService" Version="1.0.1" />
  </ItemGroup>
    
  <!-- Project Dependencies -->
  <ItemGroup>
    <ProjectReference Include="..\xIdentityHelper\xIdentityHelper.csproj" />
  </ItemGroup>

after adding dependencies. you have to extends your PushHelper module.

by following SignalR rules, for each topics you have to add an specific HUB and register it in your DI.

since all important actions for handling communications between connected peers must be handled in Hubs. at the first step you have to create a Base Class for all of your Hubs.

in this sample since we need to have Authorized HUB Actions, we add IdentityService as dependency to Helper Module, now next step is implement a BaseHub class which supports Authorized Actions based on our User Roles.

XPushBaseHub

    public abstract class XPushBaseHub : XBaseHub, IXAuthorizedPushActions, IXUserPushActions, IXGroupsPushActions {
        //
        #region Constructor ...
        protected XPushBaseHub (
            IXPushGroupStore groupStore,
            IXPushConnectionStore connectionStore
        ) : base (groupStore, connectionStore) { }
        #endregion

        //
        #region Authorized Push Actions ...
        /// <summary>
        /// an authenticated user can push a message to others ...
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [Authorize (Policy = XPolicies.User)]
        public Task UserMessageAsync (XPushMessage message) {
            //
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            return Clients.Others.SendAsync (XBasePushAction.UserMessage.GetStringValue (), message);
        }

        /// <summary>
        /// an admin user can push a message to others ...
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [Authorize (Policy = XPolicies.Admin)]
        public Task AdminMessageAsync (XPushMessage message) {
            //
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            return Clients.Others.SendAsync (XBasePushAction.AdminMessage.GetStringValue (), message);
        }
        #endregion

        //
        #region User Push Actions ...
        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> AddUserToGroup (string userName, string groupName) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            var group = GetGroup (groupName)
                .RunTask ();

            //
            var connections = connectionStore
                .GetByUserName (userName)
                .RunTask ();
            var mustAddConnections = connections
                .Where (c => !group.Connections
                    .Any (gc => gc == c.Id));
            if (!mustAddConnections.HasChild ()) {
                return result;
            }

            //
            // Add all new Connections to Group ...
            var allUpdate = false;
            mustAddConnections.ToList ().ForEach (c => {
                //
                try {
                    //
                    Groups
                        .AddToGroupAsync (c.Id, groupName)
                        .RunTask ();

                    //
                    group.Connections.Add (c.Id);

                    //
                    allUpdate = allUpdate || true;
                } catch {
                    allUpdate = allUpdate || false;
                }
            });
            if (!allUpdate) {
                return result;
            }

            //
            result = AddOrUpdateGroup (group);

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> AddUserDeviceToGroup (string userName, string groupName, XDeviceDto device) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (
                device.IsNull () ||
                userName.IsNullOrEmpty () ||
                groupName.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Find User Connection ...
            var userConnection = connectionStore
                .GetByUserDevice (
                    device: device,
                    userName: userName
                )
                .RunTask ();
            if (userConnection.IsNull ()) {
                return result;
            }

            //
            // Get Group ...
            var group = GetGroup (groupName)
                .RunTask ();

            //
            // check if connection exists in group ... 
            if (group.Connections.Any (c => c == userConnection.Id)) {
                return result;
            }

            //
            try {
                //
                Groups
                    .AddToGroupAsync (
                        userConnection.Id,
                        groupName
                    )
                    .RunTask ();

                //
                group.Connections.Add (userConnection.Id);
            } catch {
                return result;
            }

            //
            result = AddOrUpdateGroup (group);

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> RemoveUserFromGroup (string userName, string groupName) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (
                userName.IsNullOrEmpty () ||
                groupName.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Check Group Exists or not ...
            var isGroupExists = groupStore
                .IsExistsByKey (groupName)
                .RunTask ();
            if (!isGroupExists) {
                return result;
            }

            //
            // Retrieve User Connections ...
            var userConnections = connectionStore
                .GetByUserName (userName)
                .RunTask ();
            if (!userConnections.HasChild ()) {
                return result;
            }

            //
            var group = GetGroup (groupName)
                .RunTask ();
            var mustRemoveConnections = userConnections
                .Where (c => group.Connections
                    .Any (gcId => c.Id == gcId));
            if (!mustRemoveConnections.HasChild ()) {
                return result;
            }

            //
            // try to remove connections from group ...
            try {
                //
                mustRemoveConnections
                    .ToList ()
                    .ForEach (c => {
                        //
                        var isRemoved = connectionStore
                            .RemoveByConnectionId (c.Id)
                            .RunTask ();
                        if (isRemoved) {
                            Groups.RemoveFromGroupAsync (
                                    c.Id,
                                    groupName
                                )
                                .RunTask ();
                        }
                    });

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> RemoveUserDeviceFromGroup (string userName, string groupName, XDeviceDto device) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Arg ...
            if (
                device.IsNull () ||
                userName.IsNullOrEmpty () ||
                groupName.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Check group exists ...
            var isGroupExists = groupStore
                .IsExistsByKey (groupName)
                .RunTask ();
            if (!isGroupExists) {
                return result;
            }

            //
            var group = GetGroup (groupName)
                .RunTask ();
            if (!group.Connections.HasChild ()) {
                return result;
            }

            //
            // retrieve user connection ...
            var userDeviceConnection = connectionStore
                .GetByUserDevice (
                    device: device,
                    userName: userName
                )
                .RunTask ();
            if (
                userDeviceConnection.IsNull () ||
                !group.Connections.Any (gc => gc != userDeviceConnection.Id)
            ) {
                return result;
            }

            //
            try {
                //
                Groups.RemoveFromGroupAsync (
                    groupName: groupName,
                    connectionId: userDeviceConnection.Id
                );
            } catch {
                return result;
            }
            group.Connections.Remove (userDeviceConnection.Id);

            //
            result = AddOrUpdateGroup (group);

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledUser)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> SendMessageToUser (string userName, XPushMessage message) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (userName.IsNullOrEmpty ()) {
                return result;
            }

            //
            // Normalize Message ...
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            // Check user exists ...
            var userConnections = connectionStore
                .GetByUserName (userName)
                .RunTask ();
            if (!userConnections.HasChild ()) {
                return result;
            }

            //
            try {
                //
                Clients
                    .User (userName)
                    .SendAsync (
                        XBasePushAction.PushMessage.GetStringValue (),
                        message
                    )
                    .RunTask();

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledUser)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> SendMessageToUserDevice (string userName, XPushMessage message, XDeviceDto device) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (
                device.IsNull () ||
                userName.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Normalize Message ...
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            // Check user exists ...
            var userDeviceConnection = connectionStore
                .GetByUserDevice (
                    device: device,
                    userName: userName
                )
                .RunTask ();
            if (userDeviceConnection.IsNull ()) {
                return result;
            }

            //
            try {
                //
                Clients
                    .Client (userDeviceConnection.Id)
                    .SendAsync (
                        XBasePushAction.PushMessage.GetStringValue (),
                        message
                    )
                    .RunTask();

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledUser)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> SendMessageToUsers (IEnumerable<string> userNames, XPushMessage message) {
            //
            // Temp result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (!userNames.HasChild ()) {
                return result;
            }

            //
            // Normalize Message ...
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            // Check user exists ...
            var usersConnections = connectionStore
                .FindMany (c => userNames.Contains (c.User))
                .RunTask ();
            if (!usersConnections.HasChild ()) {
                return result;
            }

            //
            try {
                //
                Clients
                    .Users (
                        userNames
                        .ToList ()
                        .AsReadOnly ()
                    )
                    .SendAsync (
                        XBasePushAction.PushMessage.GetStringValue (),
                        message
                    )
                    .RunTask();

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledUser)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<string>> GetUserGroups (string userName) {
            //
            // Temp Result ...
            var resultList = new List<string> ();

            //
            // Validate Args ...
            if (userName.IsNullOrEmpty ()) {
                return Task.FromResult (
                    resultList
                    .AsEnumerable ()
                );
            }

            //
            // Retrieve User Connections ...
            var userConnections = connectionStore
                .GetByUserName (userName)
                .RunTask ();
            if (!userConnections.HasChild ()) {
                return Task.FromResult (
                    resultList
                    .AsEnumerable ()
                );
            }

            //
            // Retrieve user Groups ...
            var userGroups = groupStore
                .FindMany (pg => pg.Connections
                    .Any (pgCId => userConnections
                        .Any (uc => uc.Id == pgCId)))
                .RunTask ();
            if (!userGroups.HasChild ()) {
                return Task.FromResult (
                    resultList
                    .AsEnumerable ()
                );
            }

            //
            // prepare result ...
            resultList = userGroups
                .Select (ug => ug.Id)
                .ToList ();
            return Task.FromResult (
                resultList
                .AsEnumerable ()
            );
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<XPushConnectionDto>> GetUserConnections (string userName) {
            //
            var resultList = new List<XPushConnectionDto> ();

            //
            // Validate Args ...
            if (userName.IsNullOrEmpty ()) {
                return Task.FromResult (
                    resultList
                    .AsEnumerable ()
                );
            }

            //
            // check current user is Admin or not ...
            var connectedUser = GetUserName ();
            var connectedUserRole = GetUserRole ();
            var isAdminOrAgent = connectedUserRole.ToNormalString () == "admin" ||
                connectedUserRole.ToNormalString () == "agent";
            var isUserSame = connectedUser.ToNormalString () == userName.ToNormalString ();

            //
            // check current user ...
            if (!isAdminOrAgent && !isUserSame) {
                return Task.FromResult (
                    resultList
                    .AsEnumerable ()
                );
            }

            //
            return connectionStore
                .GetByUserName (userName);
        }
        #endregion

        //
        #region Group Push Actions ...
        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> SendMessageToGroup (string groupName, XPushMessage message) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (groupName.IsNullOrEmpty ()) {
                return result;
            }

            //
            // Normalize Message ...
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            // Check Group Exists ...
            var isGroupExists = groupStore
                .IsExistsByKey (groupName)
                .RunTask ();
            if (!isGroupExists) {
                return result;
            }

            //
            try {
                //
                Clients
                    .Group (groupName)
                    .SendAsync (
                        XBasePushAction.PushMessage.GetStringValue (),
                        message
                    )
                    .RunTask();

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> SendMessageToGroups (IEnumerable<string> groupNames, XPushMessage message) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (!groupNames.HasChild ()) {
                return result;
            }

            //
            // Normalize Message ...
            if (message.IsNull ()) {
                message = GetPushMessage ();
            } else {
                message.TimeStamp = DateTime.UtcNow;
            }

            //
            // Check Group Exists ...
            var isGroupsExists = Task.WhenAll (groupNames
                    .Select (gName => groupStore
                        .IsExistsByKey (gName)))
                .RunTask ();
            if (!isGroupsExists.All (isExists => !!isExists)) {
                return result;
            }

            //
            try {
                //
                Clients
                    .Groups (
                        groupNames
                        .ToList ()
                        .AsReadOnly ()
                    )
                    .SendAsync (
                        XBasePushAction.PushMessage.GetStringValue (),
                        message
                    )
                    .RunTask();

                //
                result = Task.FromResult (true);
            } catch { }

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> AddConnectionToGroup (string connectionId, string groupName) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (
                groupName.IsNullOrEmpty () ||
                connectionId.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Check Connection Exists ...
            var isConnectionExists = connectionStore
                .IsExistsConnectionId (connectionId)
                .RunTask ();
            if (!isConnectionExists) {
                return result;
            }

            //
            // Get Normalized Group ...
            var group = GetGroup (groupName)
                .RunTask ();
            var isConnectionInGroup = group.Connections.Any (cId => cId == connectionId);
            if (isConnectionInGroup) {
                return result;
            }

            //
            // add connection to group ...
            group.Connections.Add (connectionId);

            //
            result = AddOrUpdateGroup (group);

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> RemoveConnectionFromGroup (string connectionId, string groupName) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (
                groupName.IsNullOrEmpty () ||
                connectionId.IsNullOrEmpty ()
            ) {
                return result;
            }

            //
            // Check Connection Exists ...
            var isConnectionExists = connectionStore
                .IsExistsConnectionId (connectionId)
                .RunTask ();
            if (!isConnectionExists) {
                return result;
            }

            //
            // Check Group Exists ...
            var isGroupExists = groupStore
                .IsExistsByKey (groupName)
                .RunTask ();
            if (!isGroupExists) {
                return result;
            }

            //
            // Get Normalized Group ...
            var group = GetGroup (groupName)
                .RunTask ();
            var isConnectionInGroup = group.Connections.Any (cId => cId == connectionId);
            if (!isConnectionInGroup) {
                return result;
            }

            //
            // add connection to group ...
            group.Connections.Remove (connectionId);

            //
            result = AddOrUpdateGroup (group);

            //
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<string>> GetGroupNames () {
            //
            var groups = groupStore
                .GetAll ()
                .RunTask ();

            //
            var result = groups.Select (g => g.Id);
            return Task.FromResult (result);
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<XPushGroupDto>> GetGroups () {
            return groupStore.GetAll ();
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<bool> RemoveGroupConnections (string groupName) {
            //
            // Empty result ...
            var result = Task.FromResult (false);

            //
            // Validate Args ...
            if (groupName.IsNullOrEmpty ()) {
                return result;
            }

            //
            // retrieve normalized group ...
            var group = GetGroup (groupName)
                .RunTask ();
            if (!group.Connections.HasChild ()) {
                return result;
            }

            //
            var allResult = false;
            group.Connections
                .ToList ()
                .ForEach (cIde => {
                    //
                    var isRemoved = connectionStore
                        .RemoveByConnectionId (cIde)
                        .RunTask ();

                    //
                    if (isRemoved) {
                        group.Connections.Remove (cIde);
                    }

                    //
                    allResult = allResult || isRemoved;
                });
            if (!allResult) {
                return result;
            }

            //
            result = Task.FromResult (true);
            return result;
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<string>> GetConnectionGroups (string connectionId) {
            //
            // Validate Args ...
            if (connectionId.IsNullOrEmpty ()) {
                return Task.FromResult (
                    new List<string> ()
                    .AsEnumerable ()
                );
            }

            //
            var connectionGroups = groupStore
                .FindMany (group => group.Connections
                    .Contains (connectionId))
                .RunTask ();

            //
            var resultList = connectionGroups
                .Select (group => group.Id);

            //
            return Task.FromResult (resultList);
        }

        [Authorize (Policy = XPolicies.Admin)]
        [Authorize (Policy = XPolicies.EnabledAgent)]
        public Task<IEnumerable<XPushConnectionDto>> GetGroupConnections (string groupName) {
            //
            // Validate Args ...
            if (groupName.IsNullOrEmpty ()) {
                return Task.FromResult (
                    new List<XPushConnectionDto> ()
                    .AsEnumerable ()
                );
            }

            //
            var group = GetGroup (groupName)
                .RunTask ();

            //
            var resultList = connectionStore
                .FindMany (c => group.Connections.Contains (c.Id))
                .RunTask ();

            //
            return Task.FromResult (resultList);
        }
        #endregion

        //
        #region Private ...
        private Task<XPushGroupDto> GetGroup (string groupName) {
            //
            XPushGroupDto result = null;
            //
            // Validate Args ...
            if (groupName.IsNullOrEmpty ()) {
                return Task.FromResult (result);
            }

            //
            var isExistsGroup = groupStore
                .IsExistsByKey (groupName)
                .RunTask ();

            //
            if (!isExistsGroup) {
                result = new XPushGroupDto {
                    Id = groupName,
                    Connections = new List<string> ()
                };
            } else {
                result = groupStore
                    .Get (groupName)
                    .RunTask ();
            }

            //
            return Task.FromResult (result);
        }

        private Task<bool> AddOrUpdateGroup (XPushGroupDto group) {
            //
            var result = false;

            //
            // Validate Args ...
            if (group.IsNull ()) {
                return Task.FromResult (result);
            }

            //
            var isExistsGroup = groupStore
                .IsExistsByKey (group.Id)
                .RunTask ();
            if (!isExistsGroup) {
                result = groupStore
                    .Add (group)
                    .RunTask ();
            } else {
                //
                var updatedGroup = groupStore
                    .Update (group)
                    .RunTask ();
                result = !updatedGroup.IsNull ();
            }

            //
            return Task.FromResult (result);
        }
        #endregion
    }

one of most important things which you had to do in xPushHelper is the implementation of your HUB(s).

for this, you had to use XBaseHub class and extends your Hubs from it. here for example we create a ViewHub as follow:

XViewHub

    public class XViewHub : XBaseHub {
        //
        #region Props ...
        public static int Count = 0;
        #endregion

        //
        #region Constructor ...
        public XViewHub (
            IXPushGroupStore groupStore,
            IXPushConnectionStore connectionStore
        ) : base (groupStore, connectionStore) { }
        #endregion

        //
        #region Actions ...
        [Authorize]
        public Task NotifyCount () {
            return Clients.All.SendAsync ("NotifyCount", Count);
        }

        public Task PublicNotifyCount () {
            return Clients.All.SendAsync ("NotifyCount", Count);
        }

        public int IncreaseCount () {
            //
            Count += 1;
            return Count;
        }
        #endregion
    }

Handling WebRTC connections

there is a Base Class XBaseWebRTCHub for enable WebRTC on your projects. all thing you had to do is to extends a class from it.

XWebRTCHub

as you can see below, there is not anything to add to this class, all things handled by Base Class by default. but if there is some custom actions you need, add them here ...

    public class XWebRTCHub : XBaseWebRTCHub {
        //
        #region Constructor ...
        public XWebRTCHub (
            IXPushGroupStore groupStore,
            IXPushConnectionStore connectionStore,
            IXWebRTCConnectionStore webRTCConnectionStore
        ) : base (groupStore, connectionStore, webRTCConnectionStore) { }
        #endregion
    }

after complete all requirements inside xPushHelper module, next step is to register xPushService in your application DI, which happens on Startup.cs file.

NOTE: if you want to use Authorization and Authentication inside your Hubs, you had to register xPushService after enabling Authorization.

before moving forward, please configure xPushService as follow, in your appSettings.json file:

  
  ...

  "PushServiceConfiguration": {
    "BaseRoute": "hubs",
    "AddSupportMessageProtocol": false
  },
  
  ...

this is a sample configuration. for more info you can review xPushService Documentation

then register xPushService in Startup.cs:

    public class Startup {
        ...
        public void ConfigureServices (IServiceCollection services) {
            ...
            //
            // Register XPushService ...
            services.AddXPushService (Configuration);
            ...
        }
        ...
    }

next step is use xPushService middleware for declare and usage of your custom created HUB(s) in xPushHelper module. this must be done by an instance of XPushServiceHelper class which you have to use it for registering your hubs. then pass this to xPushService Middleware for configure them for working.

    public class Startup {
        ...
        public void Configure (IApplicationBuilder app, IWebHostEnvironment env) {
            ...
            //
            #region XPushService ...
            //
            var helper = new XPushServiceHelper ();

            //
            helper.AddHub<XViewHub> ("view");
            helper.AddHub<XWebRTCHub> ("webrtc");

            //
            app.UseXPushService (helper);
            #endregion
            ...
        }
        ...
    }

for the moment xPushService configured successfully and activated in your application.

for client side, you can follow it's related documentation.

Maintainer

Hadi Khazaee asl

https://www.saherelm.ir

hadi_khazaee_asl@yahoo.com

S
Description
xDashboard PushService Module
Readme
95 KiB
Languages
C# 100%