ASP.NET Core 2.2.1 Hosting Tips – Getting Started With SignalR Using ASP.NET Core

In this article, we’ll learn how to use Dynamic Hub in ASPNET Core SignalR. The newly written SignalR allows you to write a dynamic type of T Hub. The benefit of using dynamic hub is that the method will resolve to the runtime so that you can register any method at runtime and call it.

hfl-new-banner

Creating Dynamic Hub

This is a base class for SignalR hubs that uses dynamic keyword to represent client invocations. Basically, the idea behind Dynamic Hub is hidden in the dynamic keyword. DynamicHub is inherited from Hub class. This is an abstract class and it is implementing the DynamicHubClients which contains all the dynamic type properties.

From MSDN

“The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at runtime. The dynamic type simplifies access to COM APIs such as the Office Automation APIs, and also to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).”

A Hub contains the following properties.

  • Clients : A clients caller abstraction for a hub, where you can push message to all connected clients
  • Context : A context abstraction for accessing information about the hub caller connection. It contains the connection and claims principle information.
  • Groups : A manager abstraction for adding and removing connections from groups. Ease of managing clients grouping.
  • Events : It provide the event notification on the client connected or disconnected so that you can override these events and add your custom login.

Dynamic Hub class

//https://github.com/aspnet/SignalR/blob/dev/src/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs

public abstract class DynamicHub : Hub  
    {  
        private DynamicHubClients _clients;  
  
        /// <summary>  
        /// Gets or sets an object that can be used to invoke methods on the clients connected to this hub.  
        /// </summary>  
        public new DynamicHubClients Clients  
        {  
            get  
            {  
                if (_clients == null)  
                {  
                    _clients = new DynamicHubClients(base.Clients);  
                }  
  
                return _clients;  
            }  
            set => _clients = value;  
        }  
    }

DynamicHubClients Class

    //https://github.com/aspnet/SignalR/blob/dev/src/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs  
      
    /// <summary>  
        /// A class that provides <c>dynamic</c> access to connections, including the one that sent the current invocation.  
        /// </summary>  
        public class DynamicHubClients  
        {  
            private readonly IHubCallerClients _clients;  
      
            /// <summary>  
            /// Initializes a new instance of the <see cref="DynamicHubClients"/> class.  
            /// </summary>  
            /// <param name="clients">A wrapped <see cref="IHubCallerClients"/> that is used to invoke methods.</param>  
            public DynamicHubClients(IHubCallerClients clients)  
            {  
                _clients = clients;  
            }  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all clients connected to the hub.  
            /// </summary>  
            /// <returns>An object that can be used to invoke methods on the specified user.</returns>  
            public dynamic All => new DynamicClientProxy(_clients.All);  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all clients connected to the hub excluding the specified connections.  
            /// </summary>  
            /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>  
            /// <returns>An object that can be used to invoke methods on the specified user.</returns>  
            public dynamic AllExcept(IReadOnlyList<string> excludedConnectionIds) => new DynamicClientProxy(_clients.AllExcept(excludedConnectionIds));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on the connection which triggered the current invocation.  
            /// </summary>  
            public dynamic Caller => new DynamicClientProxy(_clients.Caller);  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on the specified connection.  
            /// </summary>  
            /// <param name="connectionId">The connection ID.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic Client(string connectionId) => new DynamicClientProxy(_clients.Client(connectionId));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on the specified connections.  
            /// </summary>  
            /// <param name="connectionIds">The connection IDs.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic Clients(IReadOnlyList<string> connectionIds) => new DynamicClientProxy(_clients.Clients(connectionIds));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all connections in the specified group.  
            /// </summary>  
            /// <param name="groupName">The group name.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic Group(string groupName) => new DynamicClientProxy(_clients.Group(groupName));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all connections in all of the specified groups.  
            /// </summary>  
            /// <param name="groupNames">The group names.</param>  
            /// <returns>An object that can be used to invoke methods on the specified user.</returns>  
            public dynamic Groups(IReadOnlyList<string> groupNames) => new DynamicClientProxy(_clients.Groups(groupNames));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all connections in the specified group excluding the specified connections.  
            /// </summary>  
            /// <param name="groupName">The group name.</param>  
            /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic GroupExcept(string groupName, IReadOnlyList<string> excludedConnectionIds) => new DynamicClientProxy(_clients.GroupExcept(groupName, excludedConnectionIds));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on connections in a group other than the caller.  
            /// </summary>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic OthersInGroup(string groupName) => new DynamicClientProxy(_clients.OthersInGroup(groupName));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on connections other than the caller.  
            /// </summary>  
            public dynamic Others => new DynamicClientProxy(_clients.Others);  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all connections associated with the specified user.  
            /// </summary>  
            /// <param name="userId">The user ID.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic User(string userId) => new DynamicClientProxy(_clients.User(userId));  
      
            /// <summary>  
            /// Gets an object that can be used to invoke methods on all connections associated with all of the specified users.  
            /// </summary>  
            /// <param name="userIds">The user IDs.</param>  
            /// <returns>An object that can be used to invoke methods.</returns>  
            public dynamic Users(IReadOnlyList<string> userIds) => new DynamicClientProxy(_clients.Users(userIds));  
        }

 

Dynamic Chat Hub Class

In this hub, we are just sending a message to the client so in the case of Hub, we have to call SendAsync by passing the client method name which is listening to the client and message or other data to send. In case of Dynamic Hub, we can call any method which is bypassed by the compiler because it has dynamic keyword. But that method must be listened to on the client side to receive the data like Send method in above class.

public class DynamicChatHub : DynamicHub  
    {  
        public async Task SendMessage(ChatMessage message)  
        {  
            await Clients.All.Send(message);  
        }  
    }

I have created a separate service and component for dynamic hub which is consuming Dynamic Hub for communication and showing the messages. You will find the same in the attached project.

Creating T of Hub

Hub<T> is a base class for a strongly typed SignalR hub where T is type of client. The T typed can be used to invoke a method on clients connected. If you want your strongly typed custom methods, this is for you.

In a Hub, we have to tell in which method client is listening, so that while writing the name of the client method, you can avoid typos and other issues.

We are going to create an Interface called IChatClient.

public interface IChatClient  
    {  
        Task Send(string message);  
    }

TChatHub Class

This class is Inherited from strongly typed IChatClient Hub<IChatClient>. In this hub class, you can call IChatClient’s methods on the client. This is the beauty of this Stack. This is just for pushing messages to the connected client.

public class TChatHub : Hub<IChatClient>  
    {  
  
        public Task Send(string message)  
        {  
            return Clients.All.Send(message);  
        }  
  
    }

Finally, we are done with Dynamic and T typed hub in SignalR.

Which Provider who can Give You The Best and Recommended ASP.NET Core 2.2.1 Hosting?

Happily, there are several reliable and recommended Web hosting out there that can help you get a handle on site speed and work to increase your ASP.NET Core 2.2.1 web rank. We are here to recommend you HostForLIFEASP.NET. HostForLIFEASP.NET is the most popular choice for people looking to host for the first time at an affordable price in Europe.

Their regular price starts at € 3.49/month only. Customers are allowed to decide on quarterly and annual plan supported their own desires. HostForLIFEASP.NET guarantees “No Hidden Fees” and industry leading ‘30 Days Cash Back’, folks might ask for a full refund if they cancel the service at intervals the first thirty days.

HostForLIFEASP.NET also give their customers an opportunity to create some cash by providing reseller hosting accounts. you’ll purchase their reseller hosting account, host unlimited websites thereon and even have the prospect to sell a number of your hosting area to others. This could be one amongst the best ways that of creating some cash on-line. You are doing not have to be compelled to worry concerning hosting stuff as they’ll beware of all the hosting desires of your shoppers.