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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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”.
18.221.165.115