- •Contents at a Glance
- •Introduction
- •Who should read this book
- •Assumptions
- •Who should not read this book
- •Organization of this book
- •Finding your best starting point in this book
- •Conventions and features in this book
- •System requirements
- •Code samples
- •Notes on the version
- •Installing the code samples
- •Using the code samples
- •Acknowledgments
- •Errata & book support
- •We want to hear from you
- •Stay in touch
- •HTTP operations
- •Polling: The answer?
- •Push: The server takes the initiative
- •WebSockets
- •Server-Sent Events (API Event Source)
- •Push today
- •The world needs more than just push
- •What does SignalR offer?
- •Two levels of abstraction
- •Supported platforms
- •OWIN and Katana: The new kids on the block
- •Installing SignalR
- •Implementation on the server side
- •Mapping and configuring persistent connections
- •Events of a persistent connection
- •Sending messages to clients
- •Asynchronous event processing
- •Connection groups
- •The OWIN startup class
- •Implementation on the client side
- •Initiating the connection by using the JavaScript client
- •Support for older browsers
- •Support for cross-domain connections
- •Sending messages
- •Receiving messages
- •Sending additional information to the server
- •Other events available at the client
- •Transport negotiation
- •Adjusting SignalR configuration parameters
- •Complete example: Tracking visitors
- •Project creation and setup
- •Implementation on the client side
- •Implementation on the server side
- •Server implementation
- •Hub registration and configuration
- •Creating hubs
- •Receiving messages
- •Sending messages to clients
- •Sending messages to specific users
- •State maintenance
- •Accessing information about the request context
- •Notification of connections and disconnections
- •Managing groups
- •Maintaining state at the server
- •Client implementation
- •JavaScript clients
- •Generating the proxy
- •Manual generation of JavaScript proxies
- •Establishing the connection
- •Sending messages to the server
- •Sending additional information
- •Receiving messages sent from the server
- •Logging
- •State maintenance
- •Implementing the client without a proxy
- •Complete example: Shared drawing board
- •Project creation and setup
- •Implementation on the client side
- •Implementation on the server side
- •Access from other threads
- •External access using persistent connections
- •Complete example: Monitoring connections at the server
- •Project creation and setup
- •Implementing the website
- •System for tracing requests (server side)
- •System for tracing requests (client side)
- •External access using hubs
- •Complete example: Progress bar
- •Project creation and setup
- •Implementation on the client side
- •Implementation on the server side
- •Multiplatform SignalR servers
- •SignalR hosting in non-web applications
- •SignalR hosting in platforms other than Windows
- •Multiplatform SignalR clients
- •Accessing services from .NET non-web clients
- •Consumption of services from other platforms
- •Growing pains
- •Scalability in SignalR
- •Scaling on backplanes
- •Windows Azure Service Bus
- •SQL Server
- •Redis
- •Custom backplanes
- •Improving performance in SignalR services
- •Server configuration
- •Monitoring performance
- •Authorization in SignalR
- •Access control in persistent connections
- •Access control in hubs
- •Client authentication
- •An extensible framework
- •Dependency Injection
- •Manual dependency injection
- •Releasing dependencies
- •Inversion of Control containers
- •Unit testing with SignalR
- •Unit testing of hubs
- •Unit testing persistent connections
- •Intercepting messages in hubs
- •Integration with other frameworks
- •Knockout
- •AngularJS
- •Index
- •About the author
SQL Server
The Microsoft database engine is another option that we can use to horizontally scale our SignalR applications. As in the previous case, we shall see that the implementation is completely trivial.
Configuring the database
The SQL Server–based backplane uses tables to store message queues circulating through the system and, optionally, the internal messaging broker for the optimized management of publications and subscriptions. It supports any version of SQL Server from 2005 onwards, both in the Express and server editions.
Creating the data structure is automatic. It will be done by the adapter when it detects that the tables and items that it needs do not exist in the database whose connection string we will supply at application startup.
Therefore, all that we have to do is create a database and ensure that the accessing user has permissions to create schemas and tables on it. After this is done, when we run the application for the first time, we will see that the structure has been generated, as shown in Figure 8-12.
FIGURE 8-12 Database schema automatically created by SignalR.
To improve performance, it is recommended that we check that the service broker is enabled on the database that we will use. This is easy to query using the following statement:
SELECT name, is_broker_enabled FROM master.sys.databases
WHERE name='YOUR_DB_NAME_HERE'
The result could be something close to what is shown in the following screen shot of SQL Server Management Studio, where you can see that, as it often happens by default, the broker is not enabled for new databases. In this case, as you can see in Figure 8-13, we have named our database SignalrScaleout.
FIGURE 8-13 Disabled broker.
Deploying and scaling SignalR Chapter 8 |
165 |
www.it-ebooks.info
If this is the case, we can enable it just as easily:
ALTER DATABASE SignalrScaleout SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE SignalrScaleout SET ENABLE_BROKER
ALTER DATABASE SignalrScaleout SET MULTI_USER
The second line of code is what enables the broker on the specified database. The first and last lines just ensure that no other users are connected when we modify the database, which would cause a concurrency deadlock. After the script is executed, if we execute the preceding query, we get the result shown in Figure 8-14.
FIGURE 8-14 Broker enabled.
Activating the backplane
For SignalR to make use of the infrastructure created on SQL Server, we must configure and activate the corresponding backplane. For this, we will first obtain the following package via NuGet:
PM> Install-package Microsoft.AspNet.SignalR.SqlServer
When the package is installed, we would just need to enter the following configuration code, with the information on the connection with SQL Server adapted to our execution environment:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var connectionString = @"server=.\SQLExpress;database=DB_NAME;" +"Trusted_Connection=yes";
GlobalHost.DependencyResolver.UseSqlServer(connectionString); // ...
app.MapSignalR();
}
}
If the connection string is not valid, if the user cannot log in, or if she is not allowed to create either schemas or tables in the database, an exception will be raised each time a client connection to the SignalR service is attempted.
We can also use a configuration object, which is useful for providing additional information. For example, the following code indicates that five tables must be created to store messages, which can improve performance by reducing contention caused by table locks in concurrent accesses. (The table structure is shown in Figure 8-15.)
166 Chapter 8 Deploying and scaling SignalR
www.it-ebooks.info
var connectionString = @"..."; // Put your connection string here var config = new SqlScaleoutConfiguration(connectionString)
{
TableCount = 5
};
GlobalHost.DependencyResolver.UseSqlServer(config);
FIGURE 8-15 Table structure.
Redis
Redis5 is a key-value open source storage system (with BSD license) that is popular in non-Microsoft environments and that has been ported to Windows by Microsoft Open Technologies.6 Its main advantage is that it provides native mechanisms to publish and subscribe (pub/sub) on an in-memory store, which offers unmatched performance in systems that use this approach and require great immediacy, such as SignalR.
Installing Redis
From the point of view of the SignalR server, there is no difference between using Redis installed on Linux or another operating system and doing so on Windows. Therefore, the choice of server to install this software is determined by the preferences or infrastructure requirements of the system to be rolled out.
If we choose to install it on Linux (as shown in Figure 8-16), we can download the source code from the repository used and build it on the server itself:
$ wget http://redis.googlecode.com/files/redis-2.6.14.tar.gz $ tar xzf redis-2.6.14.tar.gz
$ cd redis-2.6.14 $ make
|
|
|
|
5 |
Official Redis website: http://redis.io |
|
|
6 |
Official Microsoft Open Technologies website: http://msopentech.com/ |
|
|
|
|
Deploying and scaling SignalR Chapter 8 |
167 |
www.it-ebooks.info
But if we want something simpler, we can also download the software from the repository of the distribution used. For example, in systems running on Ubuntu, the following statements would install and execute the server, putting it to listen on port 54321:
$ sudo apt-get install redis-server [...]
$ redis-server --port 54321
FIGURE 8-16 Redis running on Linux.
To execute it on Windows, we also have several alternatives. One is to download the source code from its GitHub repository7 and build it using Visual Studio. Another (see Figure 8-17) is to use NuGet to get the executable file and launch it directly from the console:
PM> Install-Package Redis-64
Installing 'Redis-64 2.6.12.1'.
Successfully installed 'Redis-64 2.6.12.1'.
PM> start redis-server.exe
7 Redis for Windows in GitHub: https://github.com/MSOpenTech/redis
168 Chapter 8 Deploying and scaling SignalR
www.it-ebooks.info
Note It is possible to use the Redis-32 package for 32-bit computers.
FIGURE 8-17 Launching Redis for Windows from the NuGet console.
In either case, we could begin to connect clients to these instances of Redis openly. If we prefer to specify a particular port or a password for all the clients who will use them, we can do so at com- mand-line level:
PM> start redis-server "--requirepass YOUR_PASSWORD --port 54321"
Better yet, we can enter this password in the configuration file of the component, redis.conf.
However, in both cases, it is recommended that the password be very strong, because due to the high performance of Redis, it would be possible to perform an attack by brute force, testing tens of thousands of keys per second, and the more obvious or direct passwords would be discovered very quickly.
Activating the backplane
As in the rest of backplanes, the first thing to do is to download and install the appropriate component in the project:
PM> Install-package Microsoft.AspNet.SignalR.Redis
After that, as always, we specify at application startup that we will use Redis as support for horizontal scaling. The simplest way is by specifying the basic data of the Redis server: the host, port, password, and unique string that will be used to separate messages if the server is being used by more than one application.
public class Startup
{
public void Configuration(IAppBuilder app)
{
GlobalHost.DependencyResolver.UseRedis(
Deploying and scaling SignalR Chapter 8 |
169 |
www.it-ebooks.info