Download - Node conf - building realtime webapps
Building Realtime Singlepage Apps
@HenrikJoreteg(hurray for Twitter)
Friday, May 6, 2011
The web is in DIRECT
competition with native apps
Friday, May 6, 2011
Stop supporting crappy browsers.
Just STOP!
Friday, May 6, 2011
focus on providing compelling experiences
(with the latest technologies)
Friday, May 6, 2011
Adoption is directly related to how easy it is to tinker with.
Friday, May 6, 2011
Socket.io is to realtime what jQuery is to AJAX
Friday, May 6, 2011
Quick look at Socket.io
Friday, May 6, 2011
Servervar http = require('http'), io = require('socket.io');
server = http.createServer(function(req, res){ // your normal server code res.writeHead(200, {'Content-Type': 'text/html'}); res.end('<h1>Hello world</h1>'); });server.listen(80); // socket.io var socket = io.listen(server); socket.on('connection', function(client){ // new client is here! client.on('message', function(){ … }) client.on('disconnect', function(){ … }) });
Friday, May 6, 2011
Client<script src="http://{node_server_url}/socket.io/socket.io.js"></script> <script> var socket = new io.Socket({node_server_url}); socket.connect(); socket.on('connect', function(){ … }) socket.on('message', function(){ … }) socket.on('disconnect', function(){ … }) </script>
Friday, May 6, 2011
It’s all about state
Friday, May 6, 2011
Quick Look at Backbone.js
Friday, May 6, 2011
Backbone gives you Observable Models & Collections
var App = Backbone.Model.extend({ initialize: function () { this.bind(‘change:myProperty’, _(this.writeIt).bind(this)); }, writeIt: function () { console.log(“my prop is: “ + this.get(‘myProperty’)); }});
app = new App();app.set({myProperty: true}); // outputs: “my prop is: true”
Friday, May 6, 2011
Views just listen to model changesvar AppView = Backbone.Model.extend({ initialize: function () { this.model.bind(‘change’, _(this.render).bind(this)); }, render: function () { this.el.html(ich.app(this.model.toJSON())); return this; }});
var app = new App(); // init our modelvar appView = new AppView({ model: app, el: document.body }); // init our view
appView.render();app.set({myProperty: true}); // will re-render the whole app
Friday, May 6, 2011
Quick look at Capsule
Friday, May 6, 2011
Backbone.js +
model nesting +
serialization+
event bubblingFriday, May 6, 2011
Models shared by Server + Client(function () { ... detect and set up environment for CommonJS or browser here // Main app model exports.AppModel = Capsule.Model.extend({ type: 'app', initialize: function (spec) { this.register(); this.addChildCollection('members', exports.Members); this.addChildModel('activityLog', exports.ActivityLogPage); } }); // other models exports.Members = ...})();
Friday, May 6, 2011
Server-sidesocket.on('connection', function (client) { var app, sessionId;
// this is split out so we have a reference to it function sendClientChanges(changes) { client.send(changes); } client.on('message', function(message){ var model, collection;
switch (message.event) { case 'session': ... // Here you'd fetch your user from DB based on sessionid // you'd also get the corresponding app state that they should have access to. // `require` your shared models file and inflate or instantiate your root app model // Then grab whatever else you need and send the intial state to the client. client.send({ event: 'initial', app: app.xport() });
// bind to the root `publish` events to send any changes to this client app.bind('publish', sendClientChanges); ...
Friday, May 6, 2011
Clientside$(function () { var app = window.app = new AppModel(); window.socket = new io.Socket();
// get and send our session cookie socket.on('connect', function() { socket.send({ event: 'session', cookie: $.cookie('&!') }); }); socket.on(‘message’, ...});
Friday, May 6, 2011
Clientside cont...socket.on('message', function (msg) { switch (msg.event) { case 'initial': //import app state app.mport(msg.app); // init and render our root view view = window.view = new AppView({ el: $('body'), model: app }).render(); break; case 'change': app.modelGetter(msg.id).set(msg.data); break;
... other cases for `add`, `remove` etc. }});
Friday, May 6, 2011
Friday, May 6, 2011
Friday, May 6, 2011
Friday, May 6, 2011
Challenges
• Partially shared stateHint, sync everything, have your view render what’s relevant
• Scaling• Providing external APIs
Friday, May 6, 2011
Thank you!
me on twitter: @HenrikJoreteg (hit me up for early invite to &!)
Backbone.js: http://documentcloud.github.com/backbone/
Capsule.js: https://github.com/andyet/capsule
App Testing: http://funcunit.com,
http://mwbrooks.github.com/dominator.js/
Helpful Resources:
Friday, May 6, 2011