Chapter 3. Introducing SignalR

SignalR is a framework that facilitates building interactive, multiuser, and real-time web applications (although not only web applications, as we shall see later on), making extensive use of asynchrony techniques to achieve immediacy and maximum performance.

Originally, it was a personal project of David Fowler and Damian Edwards, members of the ASP.NET team at Microsoft, but it is now an officially integrated product in the stack of web technologies. Figure 3-1 gives a simplified idea of its position within the ASP.NET stack, where we can see Web Forms, MVC, and Web Pages as frameworks for building web applications and pages, and Web API and SignalR for building services.

A block diagram showing the conceptual location of SignalR within Microsoft?s web technology stack. At the bottom is the ASP.NET platform, and above it are the frameworks for building web applications (Web Forms, MVC, Web Pages) and those used for building services (Web API and SignalR).

Figure 3-1. Conceptual position of SignalR within the ASP.NET technology stack.

As is the case of many of these technologies, the product is completely open source (Apache 2.0 license), but with the advantages of having the full backing and support of the Redmond-based giant. Its development can be tracked, and even contributed to, at GitHub[4], where one can find the source code of the framework and related projects.

After several previews, alphas, and release candidates, version 1.0 of the product was released in February 2013, and its first important update came three months later with version 1.1.0, which included some interesting new features. After that, there were a few more maintenance updates released, mainly to solve bugs and introduce some small improvements.

The 2.0 beta 1 version was released in June 2013, and a few months later, after some other preliminary editions, the final version came out in October 2013, with important new internal features, some breaking changes, and multiple improvements with respect to its predecessor.

Despite the relatively young age of SignalR, it is currently being used successfully in a large number of real projects. For example, SignalR is behind the real-time collaboration features of Office Web Apps, used by SkyDrive, Office365, and SharePoint. Also, in completely different environments, SignalR brings to life the Browser Link feature introduced with Visual Studio 2013, as well as JabbR (http://jabbr.net), a web-based chat room service that is mainly frequented by developers, among whom you might frequently encounter the creators of this framework.

Note

The contents of this book are based on version 2.0 of SignalR. Although most concepts and techniques described here are also valid for previous versions, there might be differences in implementation due to the evolution of the development APIs.

What does SignalR offer?

Basically, SignalR isolates us from low-level details, giving us the impression of working on a permanently open persistent connection between the client and the server. To achieve this, SignalR includes components specific to both ends of communication, which will facilitate message delivery and reception in real time between the two.

In a way that is transparent to the developer, SignalR is in charge of determining which is the best technique available both at the client and at the server (long polling, forever frame, WebSockets, and so on) and uses it to create an underlying connection and keep it continuously open, also automatically managing disconnections and reconnections when necessary. As shown in Figure 3-2, we will see and use only one permanently open connection, and SignalR will take care of the dirty work under the hood, making everything function. Thus, with this framework, we frequently say that we work on a virtual persistent connection.

A diagram illustrating the virtual connection established by SignalR between a client and a server. Both ends are permanently connected through a channel that uses techniques in the backstage such as WebSockets, Server-Sent Events, forever frame, and long polling to maintain a physical connection always open between the client and the server.

Figure 3-2. SignalR virtual connection.

SignalR includes an “out-of-the-box” set of transports—or techniques to keep the underlying connection to the server open—and it determines which one it should use based on certain factors, such as the availability of the technology at both ends. SignalR will always try to use the most efficient transport and will keep falling back until selecting the best one that is compatible with the context.

This decision is made automatically during an initial stage in the communication between the client and the server, known as negotiation. It is also possible to force the use of a specific transport by using the client libraries of the framework.

Through the proposed abstraction, SignalR offers a unified programming model that is independent of the technique used in the underlying connection. As developers, we will implement our services on the virtual connection established by the framework. Thus we will have a unified programming model. That is, it is irrelevant to us whether long polling or WebSockets are being used underneath to maintain the connection: we will always use the same API, very powerful, flexible, and optimized for creating real-time applications.

Besides its ease, there is a subsequent advantage: we can also isolate ourselves from the particular aspects of the technologies and their evolution. As developers, we will focus on programming our services, and SignalR will be in charge of managing the connections and the specifics of client and server software throughout. We will not have to worry about when WebSockets will be made universally available: our services will keep adapting and will begin to use WebSockets when that happens.

But there is more. In fact, the features mentioned so far would just help us for a limited period—until WebSockets, the most powerful technology of those proposed, became available.

SignalR also includes a messaging bus capable of managing data transmission and reception between the server and the clients connected to the service. That is, the server can keep track of its clients and detect their connections and disconnections, and it will also have mechanisms to easily send messages to all clients connected or part of them, automatically managing all issues concerning communications (different speeds, latency, errors, and so on) and ensuring the delivery of messages. All this is built on a scalable architecture that will allow our applications’ ability to serve their purpose to grow as the number of users using them increases.

Moreover, SignalR includes powerful libraries on the client side that allow the consumption of services from virtually any kind of application, allowing us to manage our end of the virtual connection and send or receive data asynchronously.

In short, in SignalR, we find everything we might need to create multiuser real-time applications.

Two levels of abstraction

We have already spoken about the ability of SignalR to separate us from the particulars of the connection, offering us a homogeneous development surface which is independent of them. However, this is not completely true: in reality, there are two of them.

As shown in Figure 3-3, SignalR offers us two different levels of abstraction over the transports used to maintain the connection with the server. In fact, they make up two APIs or formulas to work on the virtual connection established.

The first one of them, called persistent connections, is the lower-level one and is therefore closer to the reality of the connections. In fact, it offers a development surface which is very similar to programming with sockets, although still on the virtual connection established by SignalR.

A diagram showing the abstraction levels used by SignalR to communicate between the client and the server. Starting at the bottom (at the lowest level of abstraction) are the Internet protocols. These support the transports used to maintain the virtual connection (WebSockets, Server-Sent Events, forever frame, and long polling). Above them are persistent connections and, finally, at the highest level of abstraction, hubs.

Figure 3-3. Levels of abstraction in SignalR.

The second level of abstraction, based on components called hubs, is much further away from the underlying connections and protocols, offering a very imperative programming model similar to RPC[5], where the traditional boundaries separating the client and the server melt away as if by magic.

Both levels have their spheres of application and will be studied in depth in subsequent chapters of this book.

Supported platforms

On the server side, SignalR can be executed on any operating system capable of running ASP.NET 4.5[6], such as Windows Server 2008 R2 or above, Windows 7 and Windows 8, and Windows Azure. However, if we want to make use of the most efficient transport, it is necessary to have at least Windows Server 2012 or Windows 8. These two options are obviously the most recommended.

The ideal web server to execute SignalR applications is IIS 8 or above, both in its full and Express editions, because this is the first version of the service that can accept connections via WebSockets. SignalR will also work in previous versions such as 7 and 7.5, but without being able to use WebSockets. In any case, the server must support extensionless URLs and operate in integrated pipeline mode.

In development time, it is possible to use Visual Studio 2012 or 2013, in both cases it being recommended that we use IIS Express for testing. Cassini is not supported. If, as is the usual case, we are working on a client edition of the operating system (such as Windows 8 or 8.1), it is not a good idea to use the full edition of IIS for testing during development due to limitations in the number of simultaneous connections allowed. Obviously, this problem will not exist when running IIS on Windows Server.

From the point of view of the client, as we shall see later on, SignalR supports a wide variety of platforms, ranging from the web to rich desktop clients and mobile devices, although the transports available will vary depending on the technology. For example, web-specific clients provide support for virtually all browsers currently available, although in some versions, WebSocket transports or Server-Sent Events will not be available.

On the official site of the product (http://www.asp.net/signalr), you can find the complete list of client platforms officially supported.

OWIN and Katana: The new kids on the block

However, as we shall see in more depth later on, the server components of SignalR are not only capable of being executed on the popular duo ASP.NET/IIS; they can work on various types of host thanks to OWIN-based architecture. OWIN is a concept that we will come across frequently throughout this book, and it is worth pausing here to explain it.

Open Web Interface for .NET[7] (OWIN) is an open specification led by the community and published under the Creative Commons license, which defines a standard interface to communicate servers with web applications, using abstractions that allow these two components, historically so tied to each other, to be decoupled. As in other occasions, this is not something radically new or out of the blue. It is derived from similar ideas already tested on platforms such as Node, Ruby, and Python.

The main goal of these indirections is twofold. First, separating applications and web servers allows more independence for both, so they can be evolved separately. For example, if SignalR had been built directly on ASP.NET, the product cycles of both frameworks would have been permanently tied, as it currently happens with Web Forms: its update depends on the arrival of a new version of the complete platform. Because this is not the case with SignalR, it will be able to evolve independently and adapt faster to the changes that this flexible and volatile world requires.

Second, this abstraction will allow our applications to be more portable, usable in various execution environments (hosters) and even on different technological platforms.

In practice, OWIN defines, among other things, a context consisting of a dictionary of values with standardized keys that the server, whichever it is, will send to the applications to provide them with information about the request, the client, parameters, and so on, as well as the way in which the applications will return the result to the host process. We might say that OWIN imposes a barrier beyond which there is to be no reference to the specific implementations of the server, isolating the application from the particulars of the latter.

The OWIN standard distinguishes five main agents that make up the chain of responsibilities needed to process requests coming from a client. Each suggests the possibilities for modularization proposed by this specification:

  • Host. The process on which the server and the application are executed.

  • Server. When executed on a host, opens a port and remains listening to communicate with the clients, processing the requests using the “protocol” defined by OWIN. Sometimes the server needs to have adaptors available that are capable of translating data into OWIN semantics. It is also possible to find software components that act at the same time as server and host of an application.

  • Middleware. Transverse components installed between the server and the application, capable of examining, directing, or modifying requests and responses to obtain a result. Normally, here we find very specialized modules that perform specific tasks such as routing requests to the appropriate component, managing security, and so on.

  • Web framework. A special type of middleware that is much more complex and reaches further than modules, because its mission is to provide an API, tools, and functionalities that simplify the process of building applications, which can be used to process requests with a higher level of abstraction. Sometimes these frameworks need adaptors to understand the information received from the server using the OWIN specification.

  • Web application. Usually built on a framework and in charge of the final processing of requests.

Figure 3-4 shows these roles in the context of the architecture of OWIN-based solutions.

A diagram illustrating the architecture of an OWIN-based solution. At the bottom is the host; a server is executed on it, which, using the appropriate adapters, communicates with frameworks or middleware modules, using the OWIN specification. Above the frameworks and middleware modules are the applications.

Figure 3-4. Architecture of OWIN-based solutions.

This architecture can materialize in diverse scenarios where these roles can be played by different software components, allowing the flexibility and independence that OWIN aims for. For example, the same SignalR application could work on the technology stacks shown in Figure 3-5.

A diagram illustrating two possible deployment scenarios of the same application with OWIN architecture. On the left side, there is a host and an IIS/ASP.NET server, which, using the OWIN specification, communicates with some middleware modules and the SignalR framework on which the application is built. On the right side are the same application and middleware in a self-host scenario, where a console application is the one acting as a host.

Figure 3-5. Two possible deployment scenarios of the same SignalR application.

Another key feature of OWIN is the application delegate or AppFunc, which is the delegate that will be in charge of processing each request. This delegate is defined as follows, receiving as a parameter the dictionary containing the data on the context of the request and returning a Task object representing the task to be processed:

using AppFunc = Func<
    IDictionary<string, object>, // Environment
    Task>; // Done

These asynchronous tasks are implemented on different middleware modules or frameworks, which can be chained to each other to create complex pipelines for the processing of requests.

Figure 3-6 shows the location of middleware components in the processing flow of requests, where they are established as middlemen through which both requests and responses pass, all within the dictionary that contains the context. This vantage position gives them the option of either capturing a request and processing it completely or simply acting as a gateway to other middleware modules of the pipeline with the possibility of altering the data of the request or its response.

A diagram illustrating how requests travel from the server to the application passing through the error handling, logging, and security middleware modules and the SignalR framework. The responses travel from the application to the server passing through the same middleware modules in reverse order.

Figure 3-6. Processing of requests through the OWIN pipeline.

But undoubtedly the most interesting feature, which represents a great improvement compared to the traditional way of developing applications on ASP.NET, is that in OWIN-based applications we will include only the modules that we need to use, thus creating lighter and more efficient applications.

OWIN is just that: a specification. It does not include any reference implementation, and it is here where Katana comes into play.

Katana[8] is an open source project created by Microsoft and distributed under the Apache 2.0 license, which contains a set of components that facilitate creating and executing web applications based on the OWIN specification.

In this project, we can find components to perform hosting of applications that are compatible with OWIN (for example, SignalR or WebAPI applications) on ASP.NET (Microsoft.Owin.Host.SystemWeb) or in self-hosting environments such as console applications or Windows services, using the Microsoft.Owin.Host.HttpListener package to receive requests directly.

It also includes many middleware modules that provide generic functionalities to the frameworks or OWIN applications using them, including compression (via the Microsoft.Owin.Compression package), CORS[9] (Microsoft.Owin.Cors), security (Microsoft.Owin.Security.*), and access to static files (Microsoft.Owin.StaticFiles).

It is good to see that functions traditionally implemented by frameworks or applications, often duplicated, have been relocated as OWIN modules that are reusable and shared by all of them. For example, not long ago, support for CORS had to be implemented in WebAPI, SignalR, or MVC independently. However, after OWIN, there is a specific middleware that can give coverage to this technique to allow cross-origin requests in a unified way.

The components of the Katana project are those on which the hosting independence of SignalR is based, so in the following chapters, we will see several examples of their use.

Installing SignalR

The easiest way to include SignalR in a project is by using the NuGet package manager. This great tool makes it easy to carry out the formerly lengthy process of downloading the components, copying the binaries to the project, and adding the references.

SignalR is distributed in diverse packages, where we can find server-side components, satellite assemblies with resources localized to different cultures, and various client implementations of these types of services.

It is possible to get the official packages available by using the graphic interface or entering the following command into the package management console[10]:

PM> Get-Package microsoft.aspnet.signalr -ListAvailable

Thus, in a web application, we will normally install the Microsoft.AspNet.SignalR package, which includes both server components and client libraries based on JavaScript. If we want to consume the services from any type of .NET application (including WinRT, Windows Phone 8, and Silverlight 5), we must install only the Microsoft.AspNet.SignalR.Client package on it.

PM> Install-package Microsoft.aspnet.signalr

It is also possible to create SignalR components directly from the development environment. In Visual Studio 2012, as long as we have installed the “ASP.NET and Web Frameworks 2012.2” update or a later one, it is possible to add components of this framework, as shown in Figure 3-7.

A screen shot showing the dialog box used by Visual Studio 2012 to add a new item to the project. Among other things, there are templates to add SignalR hubs and persistent connections.

Figure 3-7. Adding SignalR components to a Visual Studio 2012 project.

Visual Studio 2013 includes out-of-the-box SignalR templates, so we can also add components of the main available versions directly, as shown in Figure 3-8.

A screen shot showing the contents of the dialog box used in Visual Studio 2013 to add new items to the project. We can find templates to create SignalR hubs and persistent connections.

Figure 3-8. Adding SignalR components to a Visual Studio 2013 project.

In both cases, when we add these elements to our project, the necessary libraries will be downloaded and installed, and also some basic code with which to work will be included.



[4] SignalR code repository: http://www.github.com/signalr

[5] Remote Procedure Call.

[6] For ASP.NET 4 projects, SignalR 1.x could be used, although WebSockets will not be available even when it is executed on an operating system that does support this standard.

[7] Official site of the OWIN specification: http://owin.org/

[8] Website of the Katana project: http://katanaproject.codeplex.com/

[9] Cross Origin Resource Sharing.

[10] You can access the Package Manager Console in Visual Studio via “Tools > Library Package Manager > Package Manager Console”.

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

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