How to pass data to Signalr hub class - asp.net

I have some global data that stored in session["Gdata"] so that I can access these information any time I want. However, I can't access session["Gdata"] in signalr hub class.
Is there any way to access session in hub class ?

You can't use session in Signalr hub class, see this link
No access to the Session information through SignalR Hub. Is my design is wrong?
There are some solutions to your problem. You can use Standard ASP.NET security to store your global information.
You can store the data you want using this code
FormsAuthentication.SetAuthCookie("string contain your data", false);
and you can retrieve your data using this code
string GlobalData = Context.User.Identity.Name;

Related

storing signalr hub connection details in local storage

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.

Register service in startup class when signing in

I am developing an application with multiple tenants. Each tenant can be associated with a user to identify the database that it will have access to, through the connection string that is stored in the database.
The problem I am having is that I only identify this connection string at the moment the user logs in, however I need to register this connection string when the StartUp class is executed.
I tried to do this using session variables, I got the ConfigureServices method of the StartUp class to run again with the correct value, but I can not get this new configuration to take effect.
services.AddScoped<IDapperContext>(s => new DapperContext(connectionString));
I guess I need to rebuild for the new setting to take effect.
How can I do this?
Am I on the right path?
Is there any other way to solve this problem?
I recently read this article, which talks about injecting the HTTPContext into your service.
https://www.strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/
Once you have the context, you can get the authenticated user, and retrieve your connection string from a second DB or source that maps users to databases. You would have to configure your context options during construction of the context, in order to control the connection string for the context as a scoped service.
You might want to consider using a context factory instead that does this for you.
The code in startup.cs would add a context for the database with your connection strings, and then your factory would accept that as an injected dependency. Your factory would also take in IHttpContextAccessor as a dependency giving you access to the user in the context. Together you could then obtain the connection string, and wire up the DbContextOptions to pass to a new instance of your context.
This seems like the easiest approach for DI to me.

WCF Service + ASP .NET MVC application. Session expires after callback from the service

I have a following issue regarding using WCF service from my ASP .NET mvc application. Service requires a callback method to be implemented on the client side. For that I am using wsDualHttpBinding. Callbacks are being invoked and the correct info is recieved (checked using brakepoints multiple times).
The issue lies in the fact that I'm not able to save the data that I recieve when callback "SendComment" is invoked from WCF service. Callback method definition:
public void SendComment(ChatComment cc)
{
Session["Message"] = cc;
}
This is a method that should allow client (in asp .net) to recieve chat messages that are broadcasted to multiple clients from WCF service.
When I try to access Session["Message"] from the controller methods, it's value is null after I have recieved a callback. This is the main problem. I have to find a way to save the value for it to be available in current session context.
Additionally i can't access any of the other session variables I have saved right before the callback is invoked. They are always null.
Besides how do I know when I've recieved the callback? Do I have to use event handlers or somehow call the controller/view from this method?
I've already tried googling for the answer but none of the solutions explicitly state how to access the value after callback has happened.
P.S. Sessions are set to required in WCF Service.
This will not work the way you designed it. A few reasons why not:
You cannot access session from callback.
You cannot call client directly from ASP.Net MVC application.
You have too look for some other solution. I suggest you look into SignalR or if you need something simpler use DB to store data and pool from client.

calling the Caller method in SignalR hub outside the hub context

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.

SignalR hosting on separate appPool

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);
}
}

Resources