5. ¡Los usuarios quieren la ultima
informacion AHORA!
Twitter – live searches/updates
Stock streamers
Auctions
Live scores
Real-time notifications
Interactive games
Collaborative apps
Live user analytics
…
6
7. HTTP no esta preparado…
Nunca se diseño para comunicaciones real-time
La web es request-response
La web es stateless
Para solucionar esto se invento
HTML5 WebSockets
8. HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Forever Frame
– El server le dice al cliente que el response es chuncked
– El cliente mantiene la coneccion abierta hasta que el
servidor la cierra
– El servidor envia los datos al cliente seguido de un 0
– Este proceso consume threads del servidor
<script>eval("... ")</script>0
<script>eval("... ")</script>0
9. Periodic polling
– Cada cierto tiempo el cliente pregunta si hay nuevos datos
al servidor utilizando Ajax
– El tiempo de latencia minimo esta determiando por el
“polling interval”
– Desperdicia ancho de banda y latencia
Polling interval
10. Long polling
– El cliente pregunta pero el servidor no responde hasta que
tenga datos nuevos para enviar
– El cliente pregunta de nuevo cuando los datos son recibidos
o despues de que hay una time out en al coneccion
– Consume threads y conexiones del servidor
13. SignalR
¡3 en uno!
• Conexiones “persistentes” entre cliente y
servidor sobre el mejor transporte
• Abstrae el modelo de poolling subyasente
• Provee un solo modelo de programacion
15. ¿Que paso?
• El servidor hizo broadcasting del mensaje
enviado
• Los clientes recibieron los mensajes
• ¡El codigo para todo esto es facil!
• No hay polling (por lo menos no en el codigo)
16. Dos modelos de conexion
PersistentConnection
Comunica 1..N clientes
Es un IHttpHandler
Requiere que se defina una ruta
Limitado a enviar mensajes
El usuario define el “protocolo”
Hubs
Comunica 1..N clientes
Abstraccion sobre
PersistentConnection
Las rutas se mapean
automaticamente (/signalr/hubs)
Se pueden enviar mensajes y llamar a
metodos
SignalR define el protocolo
17. Hubs
• Los metodos de un Hub se pueden llamar
desde el cliente
• Los metodos de un cliente se pueden llamar
desde el servidor
– Se pueden llamar a clientes individuales
– Se pueden llamar todos clientes
– Se pueden llamar a grupos de clientes
That’s a lot of options, a lot of things to account for and a lot of different programming models. Are you going to do this?
Are you still writing separate getDocumentById and AttachEvent methods to work with the DOM? What about jQuery?
Open the previously created sample
Install-Package jQuery.UI.Combined
Add a class:
[HubName("worker")]
public class WorkerHub
: Hub
{
public void startProcessing(Event e)
{
Caller.notify("We've started processing " + e.EventName);
Clients.setProgress(10);
for (int i = 0; i <= 100; i++)
{
SignalR.Hubs.Hub.GetClients<WorkerHub>().setProgress(i);
Thread.Sleep(100);
}
}
}
Add some HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="Content/themes/base/jquery.ui.all.css" />
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.16.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR.js" type="text/javascript"></script>
<script src="signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var workerHub = $.connection.worker;
$('#progressbar').progressbar({ value: 0 });
$('#startWorkTrigger').bind('click', function () {
workerHub.startProcessing({ eventName: 'UAN12' })
.fail(function (e) {
alert("An error occured: " + e);
});
});
workerHub.notify = function (message) {
$('#notifications').html(message);
};
workerHub.setProgress = function (progress) {
$('#progressbar').progressbar({ value: progress });
};
$.connection.hub.start();
}); </script>
</head>
<body>
<div id="progressbar" style="width: 200px;"></div>
<div id="notifications" style="width: 200px;"></div>
<button id="startWorkTrigger">Start work</button></body>
</html>