Fun times with SignalR Part 1: Command Line and JavaScript Clients
- Chris Wallace
- Tue Dec 29 2015
SignalR has been on my radar for a couple of years and I've always wanted to use it in my pet projects. During the Christmas break, I've taken some time to give SignalR a go.
Since I became aware of SignalR I've always wanted to give it a go with one of my Pet Projects. I've tried it in the past with hackathon projects and tried the typical dummy 'chat' app last christmas break. But this christmas break I've decided to go one further and finally try it out on one of my projects, and what better project than my new site.
So what is SignalR?
Well according to wikipedia...
"SignalR is a server-side software system designed for writing scalable Internet applications, notably web servers. Programs are written on the server side in C#, using event-driven, asynchronous I/O to minimize overhead and maximize scalability."
In essence, SignalR is a real-time communication solution between a server and clients. SignalR primarily uses WebSockets for communication but does have fallbacks for older solutions (fallbacks which as a developer you get for free). The hierarchy of fallbacks being...
- WebSockets (most ideal but only modern browsers support it)
- Server-Sent events (also known as EventSource, supported by modern non-IE browsers)
- Forever Frame (an IE workaround, continuously loads an iframe on the page with injected scripts).
- LongPolling (continuous AJAX polling to the server).
SignalR sounds like a proprietary new-age idea but in reality is just a two-way Pub-Sub pattern. There's a central SignalR publisher server called a 'Hub' which publishes results of different functions. All clients (browsers, desktop applications, mobile apps) then subscribe to these. The clients, however, are also publishers. Able to send messages back to the hub.
So what are the practical uses?
SignalR is really intended for real-time data capture, it's fairly efficient at sending small payloads and can be scaled across servers for large applications. It is NOT intended to replace REST. First, it's not as stable as REST and secondly not as secure (if REST was TCP, consider SignalR UDP - there's a greater risk of dropping messages as an application scales).
The first real-world use of SignalR is the typical dummy 'chat' app, having a hub server represent a chatroom dispatching messages sent from individual clients. A simple google search on SignalR and this will be your first introduction. But that was the last year. I wanted to go (slightly) further.
So what have I done?
With the launch of my new site traffic was something I really wanted to keep an eye on (nothing makes giddier than knowing someone has gone out their way to try out the source that renders my ramblings!). I use GA naturally but I wanted something a bit more real-time. This is where SignalR comes into play.
I've created a small SignalR solution on GitHub called RandallR (named after the cartoon character Randall Wheems from Saturday-morning show Recess, mainly because Randall was a snitch who ratted on the smallest of actions to the authority of the playground Ms. Finster). All RandallR consists of is a small SignalR server hub in Azure with four different methods.
- Message (a simple method for relaying short messages between the clients and the server)
- Action/Event (a method for relaying an action or event of some kind with category, and label between clients, similar to a GA event)
- Declare (a method for sending a message from an admin client for all clients to consume)
- Enforce (a method for sending an action from an admin client for all clients to carry out)
Nothing dissimilar to a chat application really, just with fixed values being sent across the wire.
So how does it work?
One advantage SignalR has is that messaging can be separated into groups (in the 'chat' app analogy these groups could be considered the chatroom, so only the members of that room get the messages).
To split the levels of authorization I have three different groups: 'Randalls' and 'Finsters' and 'Admins'
- Randalls: All clients, can send messages to all other Randalls, Finsters in a certain context (think of a context as a channel or chatroom). Randalls are used to just make noise within a context and contains a single message string. Can also send events (similar to GA events) to Finsters within the context (used for logging purposes, other Randalls within the context should not be aware of events, they can snitch on each other).
- Finsters: Finsters send out messages to all Randalls within the context. They can also send actions to Randalls within the context to carry out in real-time (maybe to display a message or trigger some JavaScript).
- Admins: Admins oversee all communication between all contexts. They can see all messages, events, and actions regardless of the context. They can also send declarations which Randalls and Finsters abide by (basically a message with higher authority) and Enforced actions Randalls and Finsters must all carry out (again basically a regular action but with a higher authority). The role of the admin is to oversee and orchestrate communication across all contexts at once.
"Ms. Finster! Ms. Finster! Somebody is looking at a post on React!" "...as you were Randall."
How does it work in practice?
Really this was only a PoC, but after a field test, I'm pretty impressed with the results so far. My website has a new JavaScript SignalR client installed which sends a Message with each pageview between all the other Randalls, and an Event to all Finsters with knowledge of the page being viewed. All other clients (or 'Randalls') are aware other people are browsing the site in general, but only I (either running as a 'Finster' or Admin) know which pages people are hitting.
I can also connect to the hub as an Admin using a separate console application which sends declarations and enforced actions to all clients (when I send a declaration they're displayed as an alert in the browser....I haven't decided what enforced actions to handle yet).
So what next?
Now I have a working SignalR integration with some simple console applications and JavaScript, I want to take it further beyond the desktop. This real-time demo is a nice bit of fun for a pet project but it's not really that useful unless I have a console application always running in the background. My next aim is to consume this SignalR traffic using a phone, a raspberry pi and something else...