Yesterday, I was debugging an MVC.NET project – attempting to work out why styles were not being rendered correctly in one of my areas. Of course it turned out to be a swivel connectivity* error – as is normally the case.
In the process of debugging I used the browser’s F12 developer tools to view the network requests and statuses. What I noticed – in addition to the expected page and resource requests – was that the browser was repeatedly polling the server at 10 second intervals.
A year or so ago, I did a demo for a bunch of SharePoint developers on SignalR. I won’t go into detail on what SignalR is as you can read all about it here –
In summary, it’s a library – introduced with .net 4.5 – that makes “developing real-time web functionality easy”. Assuming the server and browser are capable, it establishes a WebSockets connection, which essentially is a long running bi-directional communication channel between the browser and the server. HTTP, in comparison, can be thought of as a uni-directional channel, as the browser initiates the communication by requesting a resource. And after some handshaking the connection is established and the response is sent by the server. Once sent, the connection is closed.
In the SignalR demo I covered the theory, looked at some sample code, and then demonstrated a real-world business application which made an asynchronous call to initiate a server intensive process, and then used SignalR to show detailed real-time progress indicators in the browser. All great stuff, but as the demo was straight after lunch – the dead zone – there were a few yawns. They did however wake up a bit when I showed how when I moved Victor Meldrew’s decapitated head around one browser window, it was moving around on all others browsers that had established connections.
Anyway, back to the unexpected polling. The requests were consistent with SignalR. My initial thought was that I had somehow merged some SignalR code with the project I was working on. It was late at night, and so my brain was getting a little befuddled. I soon ruled this out and then asked my pal Google.
To cut a long story short, Visual Studio 2013 introduced a feature called Browser Link. It creates a communication channel between Visual Studio and one or more browsers when in debug mode, enabling visual studio to refresh the content in all browsers in unison.
So a bi-directional communication channel between Visual Studio and browsers. And guess what – it uses SignalR to enable this communication. It does this by injecting a script block at the end of the Body element in each HTML page that it serves up. The script block contains functions that execute when the page is rendered by the browser, and attempt to establish the SignalR connection with the server. The script firstly does the negotiating between the browser and the server, where it determines whether both parties are capable of upgrading the HTTP connection to WebSockets. If yes, it upgrades the connection, but as you can see below, in my case it did not. Instead it went to the fall back position – of establishing a Javascipt timer interval to poll the server every 10 seconds.
So why was the connection not upgraded to WebSockets? I was using the latest version of Chrome (v39) and targeting .NET 4.5. both of which have the capabilities. The answer is that my client was a Windows 7 client, and .NET 4.5 only enables WebSockets on Windows 8 and above.
I don’t have a Windows 8 client to prove this, but I do have a brand spanking new Windows 10 Preview environment with Visual Studio 2015 Preview begging to be christened. And here are the Browser Link calls when running the app on Windows 10 against the same version of Google Chrome –
This time, after the negotiation, the protocol is switched (Status 101) to WebSockets. The WebSockets connection remains open and so there is no need to repeatedly poll the server as per the Windows 7 example.
* I’m sure most of you are too young to remember the early days of t’interweb when you had to request internet access based on a business need and have it signed off by the CTO. There was a rush to get an online presence, and eCommerce sites were initially implemented with little or no integration with internal systems. An order entry clerk would have a PC and a terminal on their desk. They read an online order’s details from the PC, swiveled their chair to the terminal to enter the details on to the internal systems, and then swiveled their chair back to the PC to confirm the order. Needless to say there were lots of “swivel connectivity” errors.