Establishing proxy-less connections

One of the biggest differences that we might have observed when comparing the .NET client library against the JavaScript one, is the presence of the dynamic proxies on the latter. SignalR takes advantage of the dynamic nature of the JavaScript language to generate proxies on the fly. Proxies greatly simplify both the calls towards the server-side Hub and the declaration of the callbacks that will be invoked from within any server-side Hub context, but the .NET client does not have this luxury. We have to resort to a calling strategy based on strings used to refer to the actual method names exposed by the Hub.

On the other hand, we have already highlighted during the Generating static files for JavaScript proxies recipe that the generation of dynamic proxies has its drawbacks, which we then solved by using the signalr.exe utility to create the proxies statically and persist them in a file to be referenced in our client pages. In this recipe, we illustrate a different option we have, which consists of avoiding JavaScript proxies completely. The proxy-less approach provides the JavaScript client with the same client model we have with the .NET client, where generic calls allow us to invoke Hub methods and declare callbacks by name. In this recipe, we'll analyze this API in detail.

Getting ready

Before writing the code of this recipe, we need to create a new empty web application, which we'll call Recipe41. We'll illustrate how to use proxy-less connections to call a Hub method from the client and how to define a callback to be invoked from the server.

How to do it…

After creating our sample empty web application, we will add the necessary pieces, as follows:

  1. We add a new Hub called EchoHub using the SignalR Hub Class (v2) template as usual. The following is the code we need:
    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Hubs;
    
    namespace Recipe41
    {
        [HubName("echo")]
        public class EchoHub : Hub
        {
            public void SayHello()
            {
                Clients.Caller.greetings("Hello!");
            }
        }
    }

    This method is simply invoking a callback named greetings on the caller.

  2. We add the Startup class with a simple standard initialization sequence, as follows:
    using Microsoft.Owin;
    using Owin;
    using Recipe41;
    
    [assembly: OwinStartup(typeof(Startup))]
    
    namespace Recipe41
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    }
  3. Let's switch to the client code, which we place inside our usual index.html page, and let's proceed step by step to analyze the specific details of the proxy-less strategy. All the necessary files to reference have already been added during the creation of the EchoHub class earlier. We just need to add them to the page as follows:
        <script src="Scripts/jquery-2.1.0.js"></script>
        <script src="Scripts/jquery.signalR-2.0.2.js"></script>

    Here, we notice the first difference: there's no reference either to the dynamic proxies endpoint or to any file containing the statically generated code for the proxies.

  4. We now open a script block where we put our code and begin by creating a connection object as follows:
        <script>
            $(function() {
                var connection = $.hubConnection();
    
                ...
            });
        </script>

    The proxy-less API is made available by invoking the $.hubConnection() function, whose return value will be used to create any generic proxy on demand. Apart from this additional feature, this connection object will play the same role we usually observed on the $.connection.hub member, which is not available if we avoid the dynamic proxy endpoint.

  5. Let's use the connection object to create a generic proxy to access the server-side EchoHub class using the following code:
                var echo = connection.createHubProxy('echo'),
                ...

    Here, we are using the general-purpose createHubProxy() method, which requires the name of the Hub and returns a proxy we can use to refer to it. This proxy has the same role as that of a dynamically generated one, but because we have no code in place to project the shape of the server-side Hub on top of it, it will just expose a few general-purpose methods to interact with it.

  6. Our sample will need a greetings() callback matching the dynamic call occurring inside EchoHub. The following is its definition:
                echo.on('greetings', function (message) {
                    console.log(message);
                });
                ...

    The on() method is the one we need in order to attach the function we want to be triggered when a callback invocation is triggered by the server-side portion of our application, as it's the case for the greetings() method. It's a generic method that requires the name of the callback and the corresponding function to call. It's probably less appealing than the dynamic version, but it's functionally equivalent.

  7. Now, we just need to start up the connection and perform a simple call towards the server Hub as follows:
                connection
                    .start()
                    .done(function () {
                        echo.invoke('sayHello'),
                    });

    The connection object is used to start the connection in the same way as we've been doing so far with $.connection.hub, by calling the start() method. After that, we define what to do when the connection is ready by specifying a callback through the done() method exposed by the promise returned by start(). That callback triggers the sayHello() server-side method using the invoke() generic method exposed by the generic proxy we obtained earlier. Again, we perform an invocation using a string to represent the name of the method, but apart from that this strategy is totally equivalent to the one with dynamic proxies. If the server-side method requires arguments, they can be passed after the method name, and the promise methods like done() or fail() are available as usual.

We can test what we wrote so far by navigating to index.html and observing the console printing the Hello! string.

How it works…

It's worth mentioning that the dynamic proxy strategy works on top of the proxy-less one. The actual core of the SignalR JavaScript client is, in fact, the proxy-less API, while the dynamic proxies are just sugar on top of it to make it more palatable and easier to use. Behind the scenes, every dynamic proxy uses the proxy-less API to make things happen.

Although the dynamic proxy strategy might make the proxy-less one look not so interesting, you might find scenarios where you have no option than using it. For example, sometimes you might not be able to determine in advance what dynamic proxy endpoint to load, or from where. In such cases, you might have to recur to the proxy-less strategy, so it's a good idea to know about it and understand how to use it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.230.107