ASP.NET SignalR is an open source library that adds real-time notifications to our application by establishing a two-way communication channel between server and client, in order to send asynchronous messages in both directions.
HTML5 specifications about WebSocket have been introduced specifically to meet this need. Although natively supported by ASP.NET 4.5, as well as in the latest versions of popular browsers, it does require the presence of the IIS 8 web server. This poses a challenge especially when we are building a site intended for diverse audiences, since we cannot be absolutely sure that all our visitors will use browsers that are compliant with this technology. This article is published from the DNC Magazine for Developers and Architects . Download this magazine from here[PDF] orSubscribe to this magazine for FREEand download all previous and current editions
SignalR connection strategy
However, there are other techniques to establish a full-duplex communication channel and luckily ASP.NET SignalR can help us with that. During the initial stages of the communication and based on the characteristics of the server and the client, SignalR automatically makes a decision about the most suitable connection strategy to use, choosing between:
· WebSocket : HTML5-related protocol that provides full duplex communication channels over a single TCP connection available in modern web browsers and web servers
· Server-Sent Events : Strategy based on the EventSource HTML5 support that allows a server to stream messages to the connected clients
· Forever Frame : Strategy based on the use of a hidden iframe element, where the chunked encoding HTTP feature is used to send stream of bytes
· Long Polling : Basic technique that involves the opening of an HTTP connection and keeping it artificially alive to create the illusion of a persistent connection.
By default, SignalR will try to use WebSocket whenever possible and if it's not available, it will gracefully fall back on the remaining ones until it picks the best option for the current environment. So with SignalR , we can establish real-time communication from server to clients: our application can push contents to connected clients instantly, rather than having the server wait for a client requesting new data.
But what about pushing content from SQL Server to ASP.NET web app?
Let’s assume we are developing a Web application to book flight tickets. Let us assume the tickets availability is stored in a database used by different booking terminals. These terminals have no idea about availability, and the only way for us to be aware of any change is to continuously poll the database for changes, and refresh the display. This approach has some disadvantages, such as a constant performance hit on the server even when there is no change in data.
For such applications, we need the server to take the initiative and be capable of sending information to the client when a relevant event occurs, instead of waiting for the client to request it.
But what about the database? How can we keep our server code aware of database changes? An easy solution is writing code that periodically re-executes a query to maintain and update the server cache, and then use SignalR to send back a message to all connected clients whenever something has changed. In software terminology, this kind of continuous checking of other programs or devices to see what state they are in, is called polling.
Figure 1: Server application polling database for changes and notifying client
Of course, this is not the best solution. We need something that automatically notifies our server about any record change, and thereby reduces round trips to the database. Some possible options are:
SQL Server Service Broker.
Let’s take a look at them. SQL Service Broker and Queue
This is a feature of SQL Server where external or internal processes can send and receive asynchronous messages reliably by using extensions of T-SQL Data Manipulation Language (DML).
SQL Server Service Broker is used to create conversations for exchanging messages. Messages are exchanged between two parties, the destination and the initiator, and allows to transmit data and trigger processing when receiving a message.
This solution, of course, requires a good knowledge of SQL Sever needed for implementing the entire database infrastructure - that is a SQL Server Queue and a Service Broker. A server side object to listen for notifications is also needed.
With SqlNotificationRequest, we are required to create our own Service Broker service and queue in SQL Server, as well as our own listener to process the sent notifications accordingly. We may choose to use this lower-level class for more granular control over the notification architecture. Following steps are involved:
Set up the Service Broker service and queue.
Create an instance of the SqlNotificationRequest class and attach it to the SqlCommand.Notification property.
Write a listener that retrieves and reacts to the received query notifications message.
This solution has the advantage to deal with a .NET class that receives notification about record changes, but still requires us to create a SQL Server Queue as well as a Service Broker.
If we want to use query notifications without paying attention to the underlying Service Broker infrastructure, the SqlDependency .NET class in System.Data is our choice. The SqlDependency class represents a query notification dependency between an application and an instance of SQL Server. When we use query notifications, SQL Server provides the queue and the service object, as they are created automatically.
While SqlNotificationRequest is a lower level API, SqlDependency is a high-level implementation to access query notifications. It allows us to detect changes on the database table. In most cases, this is the simplest and most effective way to leverage the SQL Server notifications capability by managed client applications (using the .NET Framework data provider for SQL Server). In short, SqlDependency provides capabilities to our application to monitor our database table for data changes without the hassles of continuously querying the database using timers or loops.
However, the received notification doesn’t tell us which record is changed, so it is necessary to execute another database query to fetch the data. This is an example showing the event handler triggered by SqlDependency due to a record change:
[code]private void SqlDependencyOnChange(object sender, SqlNotificationEventArgs eventArgs)
if (eventArgs.Info != SqlNotificationInfo.Invalid)
Console.WriteLine("Notification Info: " + eventArgs.Info);
Console.WriteLine("Notification source: " + eventArgs.Source);
Console.WriteLine("Notification type: " + eventArgs.Type);
}[/code] As we can see, there is no information about the record that has been modified. With SqlDependency, infact the application issues a command that contains a query, and a request for notification. The application caches the results of the query or dynamic content generated from the query results. When the application receives the query notification, the application clears the cached content. The application then re-issues the query and the notification request, when the application needs the updated query results.
Wouldn't it be better if this database notification returned us updated, inserted or deleted records, avoiding us to execute a new SELECT to refresh our server cache?
SqlTableDependency for instant notifications from Database to Server
SqlTableDependencyis an open source component that can create a series of database objects used to receive notifications on table record change. When any insert/update/delete operation is detected on a table, a change notification containing the record’s status is sent to SqlTableDependency, thereby eliminating the need of an additional SELECT to update application’s data.
Figure 2: Notification from Database to SqlTableDependency after table record changes.
The SqlTableDependency class represents a notification dependency between an application and a SQL Server table. To get notifications, this component provides an on the fly low-level implementation of an infrastructure composed of a table trigger, contracts, messages, queue, service broker and a clean-up stored procedure. SqlTableDependency class provides access to notifications without knowing anything about the underlying database infrastructure. When a record change happens, this infrastructure notifies SqlTableDependency, which in turn raises a .NET event to subscribers providing the updated record values. You can read more about SqlTableDependency at https://tabledependency.codeplex.com/wikipage?title=SqlTableDependency .
This event that gets invoked implements the generic pattern; a subscriber receives a C# object based on our needs. Let’s take a very simple example. Let’s take a database table as shown in Figure 3, and define a model that maps only to table columns we are interested in: