I'm just start testing SignalR for monitoring application . I have a control which make a call to the Hub by the client side. I noticed , each time the client make Connection.Hub.Start() it creates a new Hub instance in the server , I need to refresh my control all the time , so I don't want it to create new Hub for each one.
Is there a way to create single Hub for all clients or I'm missing something?
A Hub instance is created for each request, much like an ASP.NET Page instance is created for each request in WebForms, a Controller is created for each request in ASP.NET MVC or a WCF service instance is created for each service request when using InstanceMode.PerCall.
If you want to maintain shared state between Hub requests/instances you would need to use a static field or some other, more advanced form of state sharing (e.g. dependency injected singleton).
Related
I am trying to find the best solution to build the application at work.
1) My client has a web service, I need to have a automatically process to pull data from client web service, store in a database. The data will be displayed in a aspnet MVC web application. Once new data coming in, I want to notify the current user (something like a badge)
Question 1: I have two ideas for the process to pull data from client's web service,
A)I create a WCF service, and host it as a Windows Service
B)Create a console application and get the schedule task to run the console application
Question 2: I am thinking to use SignalR to indicate users of the new data, but in the backend how do get SignalR to check the data changes?
Thanks very much guys
Regards
Question 1: I have two ideas for the process to pull data from
client's web service, A)I create a WCF service, and host it as a
Windows Service B)Create a console application and get the schedule
task to run the console application
Did you mean WCF client? To pull data from client's web service you need a WCF client not a service? The rest looks ok to me here.
Question 2: I am thinking to use SignalR to indicate users of the new
data, but in the backend how do get SignalR to check the data changes?
SignalR is just a mean to send notifications to clients. The way you check for updates depends on the nature of the notification. So you would better elaborate on this part to get a better advice. A common way to do it is to have a notifications log table/queue which you can check for updates, process them and send to the clients. Don't forget to remove or mark processed notification in the table.
Alternatively, you can host SignalR in a windows service with a WCF client and a timer to pull data from web services. You can notify your web users directly from the windows service. Please see this article Tutorial: SignalR Self-Host
Hope it help!
I have the following environment setup (please see diagram below - open it in a new tab in case it's too small):
What I need to achieve is the following:
Add the new data (job ads that come in once or twice per day) from the old database to the new database.
Which service model should I use - WCF or Web API?
I have a smart grid system where multiple hardware devices are sending raw sensor data to an Azure Queue. Each device sends a single data packet once every minute. Multiple Worker Roles process the data packets on the queue and push the data to Table Storage. I have a Web Role which holds the application for users to view their device data and a host of other alerts and messages relating to their smart energy system. At the moment the web application just uses ajax polling at one minute intervals to get the latest data updates and any other messages and alerts. Instead of using ajax 'pulling', I'd like to use SignalR instead and 'push' the updates from the cloud when they become available. I'm not sure on what the overall architecture might look like.
So far I have added a SignalR Hub to my Web Role, just to see if I could do that. And it works fine. However, how do I trigger updates from this Hub when there are changes in Table Storage? Should I host the Hub with the Worker Roles that process the raw data, and then make a cross-domain SignalR connection from the web app (client)? Can I even associate an endpoint with a Worker Role? If I have many Worker Roles wouldn't I only be able to connect to one of them, and therefore miss data updates from other Worker Roles?
Perhaps I should create a separate Web Role to host the SignalR hub, but then how do I communicate the changes from the Worker Roles that process the raw data to the hub? Maybe I need to include another Azure Queue that takes messages from the Worker Roles regarding data updates, alerts, and any other messaging, and that queue is processed by the SignalR server. However, would this approach be scalable? If I have multiple instances of the SignalR server processing the message queue(s), would they share the same end point and be aware of all the client connections across the instances? Or maybe the Worker Roles themselves connect as clients to the SignalR server and the messages forwarded from there to the clients.
Is SignalR even the right approach to take if data is being generated at a predictable rate of once every minute for each device. Maybe for updates of this regular data ajax 'pulling' is the best approach, and I should just be using SignalR for the infrequent alerts and messages, although, again, how do I communicate these events from the Worker Roles to the SignalR server?
What overall architecture would suit my needs here?
EDIT 06-09-2014 Half the problem solved
I came across http://www.asp.net/signalr/overview/signalr-20/performance-and-scaling/scaleout-with-windows-azure-service-bus which seems to be exactly what I am after. This deals with the problem of multiple Hub server (Web Role) instances. Now I just need a SignalR client library that can run on the Worker Roles so that they can notify the Hub that new data is available, and the Hub class can then be enhanced to route the new data to the appropriate connected web clients.
EDIT 06-10-2014 A workable solution found
I have added an answer to my question of "What architecture". I thought a quick summary of my setup might be useful. I have many remote devices associated with different users posting real-time data to Azure Queues. The data posted to these queues are parsed and saved to Table Storage, by a number of Worker Roles. Web Roles provide the MVC5 web application for the users (clients) to log on and review their data. I wanted a mechanism by which when new data was posted, any connected clients would receive a real-time notification (and data tables and charts in the client apps could be updated accordingly). SignalR with Service Bus scaleout proved to be the answer.
The first part of the solution I needed was to deploy a SignalR hub that the clients could connect to, to receive any notifications sent. I couldn't use the basic SignalR solution as the MVC5 web app is hosted on a Web Role that will likely have more than one instance - the problem was how to keep all these instances synced so that whatever instance a client was connected to they'd still receive the notifications. SignalR scaleout with Azure Service Bus proved to be the answer to that part of the problem. Details of how to set this up can be found at: http://www.asp.net/signalr/overview/signalr-20/performance-and-scaling/scaleout-with-windows-azure-service-bus - it was VERY easy to setup.
The second part of the problem was how to generate the notifications originating from the Worker Roles (my queue data processors). First I needed to be able to host OWIN in my worker roles - the instructions provided at http://www.asp.net/aspnet/overview/owin-and-katana/host-owin-in-an-azure-worker-role were more than sufficient. Once this was done I created an empty Hub instance with the same name as the one deployed on my Web Roles (it was empty because I didn't expect to have an clients connected to it directly), and changed the Startup class to:
public class Startup
{
public void Configuration(IAppBuilder app)
{
String connectionString = "[Service Bus Connection String]";
GlobalHost.DependencyResolver.UseServiceBus(connectionString, "[App Name]");
app.MapSignalR();
}
}
With this in place if I want to send a notification out to the clients, from the Worker Roles, I do something like:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.clientMethod("[Message]");
What really happens is that a copy of the message gets pushed to the backplane (Service Bus) and is picked up by the Web Roles and pushed out to the connected clients. In reality I will check who is online (in the Web Role Hub instance I override the OnConnected method to save the user's connection id in their profile which is stored in Table Storage), and only create notifications that are associated with those users to reduce SignalR traffic.
We're attempting to migrate from SignalR 1.x to SignalR 2.x and have run into some issues.
The app has been using SignalR 1.x to do "real time" (push) communcations between the backend and frontend clients. In SignalR 1.x, we had access to the System.Web HttpContext sessions state. Specifically, we were using the SessionId to keep track of and manage active SignalR connections.
We're now attempting to upgrade to SignalR 2.x. Unfortunately, access the the System.Web HttpContext is no longer supported. This is because SignalR requests are handled before the session state module is initialized.
Now we're tasked with coming up with some other way to uniquely track connections other than the SessionId. One thought is to grab something from the client side and pass into our initial request for subscribing to SignalR notifications. I was looking at these request cookies and wondered if there was something that I could use there.
Any thoughts on this?
Thanks,
JohnB
Instead of Sessions, SignalR makes use of Connections. According to the http://asp.net/signalr website, "Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context.ConnectionId property of the hub context. . . "
Also, the Context still has a User property, retaining the Identity (and thus username) of the user (Context.User.Identity.Name)
Therefore, instead of using Sessions, you can use ConnectionId's to identify users.
This page goes into more details: http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections
All,
I have a ASP.NET Web API project that is making a REST call to my service layer in another project. The service project's data access is via Entity Framework 4.3. The connection string in the web.config files is set to use Integrated Security.
What is happening is, the name of the server, "server A", is being passed to the service layer, and failing authentication against SQL Server. There isn't a user account named "server A."
More specifically this is what the architecture looks like
jquery file making an api controller via POST to a method within the API controller
API controller method references the service layer DLL, and calls a method within the service class
The service class is calling a method in a repository class that uses DbContext to connect to SQl Server 2008 table.
Is there something specific I need to be doing when using the Web API framework in order to pass the correct user name down to EF?
Any help would be appreciated.
Derek
The problem is double hop impersonation. You can read about it by this link.
But i'm not sure that such impersonation is possible via REST. I recommend you use database via special account, not integrated security.