Creating responsive and interactive web applications has always been one of my hidden dreams. One of the biggest show stopper has been the communication between server and clients. The rise of websockets now open some space for a brand new kind of applications; but we need a library that makes things 'easy' for us and that is able to fall back on previous solutions when the latest technologies are not available.
Suddenly on the ASP.NET scene appears SignalR: a persistence connection abstraction library that helps ASP.NET developers deal with 'real time' client-server communication sceneries.
3. Who am I ?
Alessandro Giorgetti
Co-founder/Owner of www.grupposid.com
Co-founder of
Email: alessandro.giorgetti@live.com
www: http://www.primordialcode.com
Twitter: @A_Giorgetti
PrimordialCode
4. Real Time Applications : the
«customer» viewpoint
• You (the «customer») want data!
• You need them NOW!
• Real Time!
It’s a ‘today’ reality:
• Twitter / Facebook / many more…
• Notifications.
• Auctions / Stock trading / Banking.
• Collaborative apps.
PrimordialCode
5. What do we «devs» mean with ‘Real
Time’ applications ?
• Persistent Connections between endpoints.
• Two way communication (full-duplex).
• Low Latency ( :D ).
• Low overhead.
• Over the «wire» (intranet/internet/generic
communication medium).
PrimordialCode
6. Real Time Web Apps
Our worst enemy:
HTTP
• Stateless
• Request – Response communication pattern.
• Defo: not for real time.
PrimordialCode
7. WebSockets a «god sent» HTTP
extension
«the goods»
• Two way Full Duplex communication.
• Traverse proxies (ports: 80/443).
• Low overhead (2 bytes or so).
• Low latency (~50 ms).
• W3C standard.
• It’s a raw socket (flexibility).
PrimordialCode
8. WebSockets - interface
[Constructor(in DOMString url, optional in DOMString protocol)]
interface WebSocket {
readonly attribute DOMString URL;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
// networking
attribute Function onopen;
attribute Function onmessage;
attribute Function onclose;
boolean send(in DOMString data);
void close();
};
WebSocket implements EventTarget;
PrimordialCode
9. Using WebSockets
var myWebSocket = new WebSocket
("ws://www.websockets.org");
myWebSocket.onopen = function(evt) { alert("Connection
open ..."); };
myWebSocket.onmessage = function(evt) { alert(
"Received Message: " + evt.data); };
myWebSocket.onclose = function(evt) { alert("Connection
closed."); };
myWebSocket.send("Hello WebSockets!");
myWebSocket.close();
PrimordialCode
10. WebSockets: it’s not always gold all
that shines!
«the badz»
• It’s a «raw» socket.
• Not all browsers support it.
• Not all servers support it.
• Not all proxies support it.
• Is it a standard then?
PrimordialCode
11. How to write RT apps then?
Techniques to simulate Real Time
communications:
• Polling.
• Long Polling.
• Forever Frame.
• Server Sent Events.
PrimordialCode
12. Polling: the stubborn approach
Server
Response
Request
delay Client
Time: requests event ‘n’ seconds (fixed time)
PrimordialCode
13. Polling
• High overhead on requests: headers and
such…
• High overhead on response: same as before…
• High latency.
• Waste of bandwith.
• Waste of resources.
PrimordialCode
14. Long Polling: the kind gentleman
approach
Server
Response
Request
Variable delay Client
Time: requests event ‘n’ seconds (variable)
PrimordialCode
15. Long Polling
• High overhead on requests: headers and
such…
• High overhead on response: same as before…
• Medium latency.
• Waste less of bandwith.
• Waste of resources.
• Better than the previous one: less requests.
PrimordialCode
16. Forever Frame: the IE way
IFRAME ("Forever frame"): Loading a page in an IFRAME that incrementally
receives commands wrapped in <script> tags, which the browser evaluates as
they are received.
• Data is sent out in chunks.
• Add an IFrame to the page (its content length is declared to be indefinitely
long).
• Load in the IFrame a page with a script in it (execute it to get your chunk
of data).
• The next chunk of data arrives in the form of another script that is
executed again.
• The cycle goes on and on and on...
• It causes pollution in the long run…all those script tags stays there even if
you don’t need them anymore.
PrimordialCode
17. Server Sent Events: the others way
From Wikipedia (handle with care):
Server-Sent Events (SSE) are a standard describing how
servers can initiate data transmission towards clients
once an initial client connection has been established.
They are commonly used to send message updates or
continuous data streams to a browser client and designed
to enhance native, cross-browser streaming through a
JavaScript API called EventSource, through which a client
requests a particular URL in order to receive an event
stream.
PrimordialCode
18. SSE - EventSource
Javascript API: subscribe to a stream and await for messages
if (!!window.EventSource)
{
var source = new EventSource('stream.php');
}
else
{
// Result to xhr polling :(
}
source.addEventListener('message',
function(e) { console.log(e.data); }, false);
source.addEventListener('open',
function(e) { // Connection was opened. }, false);
source.addEventListener('error',
function(e) { if (e.readyState == EventSource.CLOSED),
false);
PrimordialCode
19. SSE – the stream format
EVENT STREAM FORMAT
Sending an event stream from the source is a matter of
constructing a plaintext response, served with a text/event-
stream Content-Type, that follows the SSE format. In its basic
form, the response should contain a "data:" line, followed by
your message, followed by two "n" characters to end the
stream:
data: My messagenn
There are many more options, for a quick reference:
http://www.html5rocks.com/en/tutorials/eventsource/basics/
PrimordialCode
20. So many options and a big
Headache !
How to survive ?
PrimordialCode
21. Introducing: SignalR
• Persistent Connection Abstraction communication library.
• Abstracts protocol and transfer (choses the best one).
• A single programming model (a unified development
experience).
• Extremely simple to use.
• Server-side it can be hosted in different «environments»
(ASP.NET, console apps, windows services, etc…).
• Client-side there’s support for: Javascript clients, .NET
clients, WP; provide by the community: iOS, Android.
PrimordialCode
22. SignalR: setup demo
Demo: how to setup SignalR,
GitHub or NuGet,
see websockets in action.
PrimordialCode
25. SignalR
«Low level» API
• Persistent Connections
manages the connection and the «raw» stream of data.
«High level» API
• Hubs
provide advanced support for internal routing (calling
functions on server & clients), connection and
disconnection tracking, grouping etc…
PrimordialCode
29. SignalR: Scaling Out
Every instance lives on its own, to make them
communicate and share data we need a …
Backplane:
• Redis.
• Azure Queues.
• Sql Server (soon to be ?).
• Build your own!
PrimordialCode
30. SignalR: backplane
Demo: use an in-memory database
to setup a message bus between
SignalR running instances
PrimordialCode