After learning how to perform a connection and customize the transport strategy, let's move to the natural next step: calling a server-side Hub method. As we have done so far in this chapter, we'll use the SignalR dynamic proxy generation feature that allows us to perform client-to-server calls in a more natural way. The alternate available approach will be illustrated in the future recipes.
This recipe and the remaining ones of this chapter have a clear goal of illustrating the client-side code in a very detailed way, and that's because we have several important features to explain. For this reason, we'll show the code and comment on it step by step, instead of going directly to its final version and commenting on it afterwards.
Let's proceed to the code, starting with the server side. Perform the following steps:
EchoHub
, and add the following code to it:using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; [HubName("echo")] public class EchoHub : Hub { public string Say(string message) { return message; } }
The content is trivial; it contains just a Say()
method that returns the supplied string.
Configuration()
method just calls app.MapSignalR();
in order to initiate SignalR properly. We have already done this step several times. You can refer to the previous recipes for more insight.index.html
.<script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script src="/signalr/hubs"></script>
<script> ... </script>
$(function() { ... });
This is to guarantee that we operate only when the DOM of the page is properly loaded. It's not always necessary, but it's generally a good practice.
hub
object as shown in the following line of code:var hub = $.connection.hub;
With this object, which we already briefly described in the Starting a Hub Connection recipe, we will later be able to actually connect to the server through the Hubs API.
echo
Hub as shown in the following line of code:var echo = $.connection.echo;
This reference is a handle to an autogenerated proxy that points to our server-side EchoHub
; its name comes from the value we supplied to the HubName
attribute that we used to mark our Hub.
At this point, you might be slightly confused by the two members of $.connection
: hub
and echo
. When the Hubs API is used, $.connection
will expose each server-side Hub as a member whose name will match either the name of the concrete Hub type or the value specified by the HubName
attribute. Additionally, $.connection
exposes the hub
member, which is not a Hub, but an entry point that we can use to manage the underlying connection and access a set of methods and properties exposed by the Hubs API itself. We need the latter to perform general purpose actions such as starting the connection, and we use the other ones to access specific Hubs.
Let's move on. We will perform the next set of steps to fill EchoHub
:
var started = hub.start();
The start()
call, as already mentioned in the Starting a Hub connection recipe of this chapter, returns a JavaScript promise
object that we'll use to set up a function to be called back when the connection is ready.
started.done(function() { ... });
The done()
method allows us to specify the actual function to be called when the connection is ready. In this way, we can guarantee that any other interaction will be performed when everything is in place; otherwise, SignalR will complain.
done()
callback. We know that inside this function, we are allowed to use our Hub proxy to perform any call towards the server, as shown in the following code:var call = echo.server.say("hello!");
The echo
proxy exposes a server
member on which we can call any method that is exposed by the server-side Hub. This is where we can really see the proxy generation shine because each Hub method has been made available by the dynamic endpoint. The return value of any remote call is again a JavaScript promise
object, as for the connection startup method, because every call going through the network is executed asynchronously. We'll use this promise
to read the return value of the Hub method.
In this specific example, we call the say
method exposed by EchoHub
, and it's interesting to observe how we write the method call with the initial s
in lower-case (say
instead of Say
). SignalR automatically matches the lower-case (also known as camel case) call on the client, which is more natural in a JavaScript environment, with the corresponding upper-case (or Pascal case) method definition on the server side, which is the usual way to name public methods when writing C# code.
done()
callback onto the promise
object that we just assigned to the call
variable:call.done(function(message) { $('#message').html(message); });
The callback declares a parameter that will be set to the value returned by the server-side Hub method. In this way, we can use it to set the content of a DOM element on the page with an ID equal to message
.
We wrote some pretty verbose code to illustrate the steps one by one; but of course, in real applications, we could write it in a much more synthetic way, avoiding the intermediate variables hub
and echo
, as shown in the following code:
$(function() { $.connection.hub .start() .done(function() { $.connection.echo.server .say("hello!") .done(function(message) { $('#message').html(message); }); }); });
If we visit the index.html
page, we will see a hello! message printed on the page as a result of a process where the following actions are performed:
done()
callback).done()
callback), we print it.