Page 54 - MSDN Magazine, May 2018
P. 54
Cutting EdgE DINO ESPOSITO Under the Covers of ASP.NET Core SignalR
SignalR is the latest addition to the ASP.NET Core platform, and a long-awaited one at that. I dare say that only now with SignalR on board can we really start looking at ASP.NET Core as ready for prime time for all types of applications. No serious Web application today can do without some form of asynchronous notification and real-time capabilities.
The SignalR you know from ASP.NET has been totally rewrit- ten and resides now in the family of ASP.NET Core libraries. In my column last month (msdn.com/ magazine/mt846469), I offered a quick tour of the features and capabil- ities of the new ASP.NET Core SignalR. In this column, I’ll dive into the internal machinery.
Figure 1 Details of the Initial Starter Request
SignalR is an abstraction layer for bidirectional, two-way remote procedure calls (RPC) and works over a variety of transport protocols. It’s host-agnostic and not limited to HTTP. In the latest version, it can transfer binary data and not just JSON-based mes- sages. When configuring SignalR either for ASP.NET or ASP.NET Core, you can select the transport protocol and the message pro- tocol. If you don’t make an explicit choice, the transport protocol is chosen automatically and most of the time it turns out to be WebSockets. The message protocol, by contrast, is based on JSON. Let’s take a look at what happens when a client—for example, a Web client—sets up a connection with a server endpoint. The code below starts a connection.
var progressConnection = new signalR.HubConnection("/progressDemo"); progressConnection.start();
If you monitor the Web traffic generated by this code with a tool like Fiddler, you’ll see that two HTTP requests are sent. Figure 1 shows the details of the first request that bootstraps the conversation.
The initial request is an HTTP POST targeted at the SignalR route specified in startup class followed by a /negotiate segment. The following code shows how to define a SignalR route:
app.UseSignalR(routes => {
routes.MapHub<ProgressHub>("/progressDemo"); });
Based on the route, the initial call will target the URL: /pro- gressdemo/negotiate.
Note that in preview versions of SignalR the OPTIONS verb was used for the same purpose. The SignalR server endpoint returns a JSON object configured as follows:
{
}
As you can see, the JSON response contains two things: the unique ID of the just-established connection, and a list of trans- port protocols available for use. The sample code indicates that WebSockets, ServerSentEvents and LongPolling can be used given the client and server configuration. What happens next depends on the transport actually chosen by the client.
SignalR tends to use WebSockets if possible. If not, it checks ServerSentEvents and after that falls back to LongPolling. If WebSockets can be used, then an HTTP GET request is placed to the same URL as before. This time the request also adds the con- nection ID as a query string parameter. The GET request is actually
"connectionId" : "b6668ac0-1083-499f-870a-2a5376bf5047", "availableTransports" : [
"WebSockets", "ServerSentEvents", "LongPolling"
Code download available at bit.ly/2FxCKTs.
50 msdn magazine
]