I am new to .NET SignalR. I see most of online SignlaR examples for beginners, in a custom Hub class, there is a straight forward way to create custom Hub methods in a derived Hub class without using IHubContext object in those Hub methods. Under which circumstance should I use IHubContext object? Thank you for your help.
There is a newer way to get the hub
DefaultHubManager hd = new DefaultHubManager(GlobalHost.DependencyResolver);
var hub = hd.ResolveHub("AdminHub") as AdminHub;
hub.SendMessage("woohoo");
This will resolve your to your concrete hub object.
Related
https://learn.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-3.1#create-and-use-hubs says "Create a hub by declaring a class that inherits from Hub, and add public methods to it. Clients can call methods that are defined as public.".
I would like to have public methods in my hub (callable from other places in the server), that are not exposed to the clients. Surely there must exist an attribute to make public methods not callable? Or is this really not supported?
Thanks.
You can't call methods on the hub from other places in your server. The Hub methods are only for the client to call. You also should not be manually creating or storing Hub instances, Hubs are created/controlled/destroyed by the SignalR library.
I am using signalr client in my application. I want to establish the connection and use the same in all the pages. I could get the connection. To access the hub details i am trying to store it local storage.
Below is the hub details i am getting once i build it.
localStorage.setItem("thisConnectionHub",JSON.stringify(thisConnectionHub));
It is stored as below.
HubConnection is missing in this. Because of this i could not listen to any methods from server.
Any ideas how can i get this work.
Thanks,
If you want to use the same connection, you need to create a service that can be #injected in your components so you don't lose the context and can invoke the client side methods that instead will invoke the hub methods. This is called dependency injection. Your service will establish the connection on the application init and then other components would use the hubConnection methods that you will declare public or event implement an interface to do that.
I have a question in my mind about the Caller method of SignalR. In the hub method we can call a client side function like this.
Clients.Caller.addContosoChatMessageToPage(name, message);
but when i use to call it from outside the hub context it is not found or not implemented?? like this..
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.Caller.reportProgress(recordCount,totalCount);
Can someone enlighten me in this part or is there other way to implement it..
by now i use to implement this
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.User(CurrentUser.Usernm).reportProgress(recordCount,totalCount);
but now we are not claim based authentication so it will be a problem if the same usernm are logged..
Outside of the hub, there obviously is no caller because the server is the one who initiates.
If you are worried about unique user names, you'll need to implement a custom IUserIdProvider, or you need to manage connection ids per user in some other way. Then you could call
context.Clients.Client(connectionId).reportProgress();
which would be unique.
Getting a reference to the client using the SignalRConnectionId is pretty simple via the GlobalHost class. Is there a way to get a reference to a hub instance associated with that client/connection? In other words, given the client connection Guid, can I get a reference to a hub instance that's talking to that client? The reason I want to do this is so I can invoke an instance method on the hub from somewhere else in the server.
It is not possible to get a Hub instance from outside of the SignalR Hub pipeline or the Hub itself.
Hubs are ephemeral in SignalR. Generally a new Hub is instantiated for each invocation, and then disposed immediately after.
This means that a single WebSocket connection can have an arbitrary number of associated Hub instances over its lifetime. Moreover, unless there is an ongoing invocation, it's unlikely that there is even an associated Hub in existence.
I would suggest replicating the Hub instance method you want to call with a static method that takes an IHubContext as a parameter. You can get the IHubContext using GlobalHost.ConnectionManager.GetHubContext.
My web application have a chat app module built on SignalR hub.
The app will have 1000+ concurrent users. I want to host the Chat Module on a separate app pool to separate it from my main application so that SignalR does not bottleneck my main application.
I'm not sure how to go about it. I've built a simple Chat system (much like Google Talk) tied to my Main Web project using Hub class and client side code resides in Site Master since it will be common across the application.
i also want to be able to call Hub method outside the Hub class. For example, an admin might assign certain task to an user from admin panel. So, from the Controller method after completing service operation (task assignment) successfully, I want to send a SignalR message to that particular user. Should I be using Hub or Persistence connection to achieve both the goal? Host SignalR on a different port? I'd appreciate some guidance on this. Thanks!
Not that I think you necessarily have to do this, but I can understand the desire to separate. To do this you would have to have your MVC application call hub methods as if it was a SignalR client itself. You can either do this by putting separate methods on the same hub or by adding a secondary hub which exists solely for this kind of inter-app communication.
I would probably use the latter approach of having a second hub because you can secure it differently. If you go this route, you would simply get the HubContext for the primary hub and make whatever calls you want/fire whatever signals you want to it. That might look something like this:
public MyInterAppCommunicationHub : Hub
{
public void SendSystemAlert(string message)
{
HubContext myPrimaryHubContext = GlobalHost.ConnectionManager.GetHubContext<MyPrimaryHub>();
myPrimaryHubContext.Clients.systemAlert(message);
}
}