i need to know how SignalR Generates Hubs at run time , how he knows which class to generate to hub, and when it does it , is it on startup or it is on first or for each request.
i know that SignalR use different types of transports.
is there a specific hub proxy for each transport type also?
The client creates a proxy for each hub. You invoke hub methods using these proxies. These proxies make sure that the messages sent to the server contain the name of the hub to create (you can find the description of the SignalR protocol here). The server parses the message and extracts the hub name and creates a hub instance using IHubActivator instance registered in the DI container.
Hub instances are transient and are created for each request and then discarded when the hub method invocation is complete.
Transport are independent on the hubs/proxies - they are means to move the data regardless of what the data actually is.
Related
If the answer is each hub has its own connection , how expensive are really these connections, lets say we have 3 hubs for 30K user connected is there really a performance gain if I reduce them to one hub ?
From docs :
Each connection object that you create encapsulates information about
a connection to a SignalR service that contains one or more Hub
classes. To communicate with a Hub class, you use a proxy object which
you create yourself (if you're not using the generated proxy) or which
is generated for you.
Also
All clients will use the same URL to establish a SignalR connection
with your service ("/signalr" or your custom URL if you specified
one), and that connection is used for all Hubs defined by the service.
In the SignalR (server) hub I want do a license check. If the check negativ then I want in the OnConnected of the Hub block the connection. The client should get in the Hub start the Task as canceled with a message (no valid licence).
When I return a Task with a Aggregate Exception in the OnConnected of the SignalR Hub then the client gets a fault state, with a timeout exception.
How can I block the connection to the SignalR hub and give the client a message why I have block the connection?
As far as I know you can't just start or stop connections already on the server. The client has to disconnect itself. If you want to use the hub for licence check you need to have the client connect - send licence info - server checks and if it is invalid call $client.disconnect on the client.
The other option like blorkfish mentions is to allow them to connect, add them to a list and check this when they call methods on the server.
I don't think that you should block the connection with an Exception. Your client would then not be able to tell if there was a genuine error in the SignalR connection.
Rather send a specific SignalR message back that there is no license - and then manage the connection object on the server side.
Keep a list of licensed connections, and a list of unlicensed connections.
So instead of using Clients.All to broadcast, use Clients.Client("< client_connection_id >") to broadcast.
Hope this helps.
I am learning Signal-R, and this is something that has been in my head during all time.
How does Signal-R fits in the IIS/ASP.NET life cycle?
How long does the Hubs live (I see they have re-connection semantics)?
Does IIS does prevent the shutdown of an AppDomain that has a persistent connection?
It is my understanding that IIS is designed to handle request-response scenarios. A request hits IIS, this finds the AppDomain, activate it, and then pass the request to it. And after an idle time, shutdown the AppDomain. If the request takes too long, a timeout exception is thrown.
Now let´s imagine that I have another application that broadcast information through a TCP socket. I want my javascript clients to get that information in real time, so I create a Signal-R web application. I can create a TCP client on application start, but what does guarantee that IIS is not going to shutdown the whole thing after some time with inactivity?
I could self host the Signal-R app in a window service, but then I would have to use a different port, enable cross domain, etc... Many problems for deployment. But, I am concerned about using an ASP.NET MVC application for this, since it looks to me like fitting a driving wheel in a motorbike.
Cheers.
SignalR in IIS/ASP.NET Lifecycle
SignalR uses Owin: http://owin.org/
A good article on Owin here: http://msdn.microsoft.com/en-us/magazine/dn451439.aspx
Hub object lifetime
From the SignalR docs: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#transience:
You don't instantiate the Hub class or call its methods from your own code on the server; all that is done for you by the SignalR Hubs pipeline. SignalR creates a new instance of your Hub class each time it needs to handle a Hub operation such as when a client connects, disconnects, or makes a method call to the server.
Because instances of the Hub class are transient, you can't use them to maintain state from one method call to the next. Each time the server receives a method call from a client, a new instance of your Hub class processes the message. To maintain state through multiple connections and method calls, use some other method such as a database, or a static variable on the Hub class, or a different class that does not derive from Hub. If you persist data in memory, using a method such as a static variable on the Hub class, the data will be lost when the app domain recycles.
Your long running TCP client
This is not a problem with SignalR. Your TCP client can be shutdown by IIS: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
I would rather make the TCP client run in a windows service. The TCP client receives TCP broadcast messages and forwards the messages to the Hub using the SignalR .NET client.
Hubs are recreated on each SignalR request, so if you need a persistent connection you may have to look into using static vars or dictionary to hold state. But as you point ASP.NET can restart for a variety of reasons.
It depends on what persistancy you really need. If you have a connection that MUST stay alive at all times and cannot be torn down and reestablished then hosting in IIS is not the right choice. However, if you can re-establish the same connection after a shutdown, then maybe this can still work.
You can do quite a bit in making sure that ASP.NET apps don't shut down in recent versions of IIS:
http://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive
If that's not enough for you running as a separate service is an option. If you run as a service on the same IP address there are no cross domain concerns. Here's more info on running SignalR using a Windows Service:
http://weblog.west-wind.com/posts/2013/Sep/04/SelfHosting-SignalR-in-a-Windows-Service
I connect to my server, which is load balanced for an alias to point to 2 servers, 01 & 02 and it round-robins connections for arguments sake. I can connect to the hub without a problem, and I can even send stuff to the server, but when it goes to return it to the client, I never get my methods invoked. If I bypass the load balancer and use the server name explicitly, it always works just fine.
I'm even tracing it, and I send back the message from the exact originating server with the Clients.Client(clientId).completeJob(stuff), and that executes fine on the server, but if I ContinueWith, it never gets finished.
Oh, and it's connected with server sent events. Am I missing something or is this just not supported?
Server-sent events establishes a long running connection, but unlike WebSockets, it isn't bidirectional. The connection can only be used to push data to the client.
SignalR uses regular XHRs to send data from clients when the WebSocket transport is unavailable. This means that the load balancer will likely route client-to-server hub method invocations to a server different than the one the client originally established a server-sent event connection with.
The server executing Clients.Client(clientId).completeJob(stuff) likely doesn't own the connection that would allow it to push a message to the specified client. (Though returning a value from a hub method on the server will send data back to the client via the same connection that invoked the method.)
SignalR can work behind a load balancer. It just requires a little more setup so all the SignalR servers can communicate with each other via a backplane such as Service Bus or Redis. This allows messages to get dispatched to the server that owns the server-to-client connection.
https://github.com/SignalR/SignalR/wiki/Azure-service-bus details how you can setup a Service Bus backplane on Azure.
In some articles on different sites i read that we only serialize/deserialize the state of object.On the deserialization side actual class definition should be present.
If that is the case, In case of EJB then how we get the Ejb home and ejb remote implementaion from server(which is on remote machine) as on client side we just have home and remote interfaces.
In addition to the home and remote interfaces, you need "stub" implementations of those classes on the client. These are generated in a vendor-specific way during application deployment, or in same cases, they are generated dynamically on the client. In any case, the server-side implementation is never needed on the client: when a method is invoked on a stub, the method request is sent over the network, and the server executes the logic when it receives it.