Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SocketStream

 SocketStream

A talk about SocketStream, given at Node.js Cambridge November 2013

Paul Jensen

November 12, 2013
Tweet

More Decks by Paul Jensen

Other Decks in Programming

Transcript

  1. With a traditional web app, the user has to refresh

    the page to see new information
  2. Time Server Client Even though there was no new information,

    the server still had to serve the HTTP request
  3. Overview • The server becomes a REST API serving JSON

    • HTML compilation is done on the client • As a result, less processing & bandwidth is consumed by the server
  4. Time Server Client Goal The server sends a message to

    the client that an action has occurred
  5. Overview • We can replace AJAX polling with WebSockets, and

    provide a better user experience as a result • We also remove the need to make redundant polling requests back to the server. • We use WebSockets for sending/receiving JSON
  6. Also, we don't mandate using a specific client-side framework !

    You can use BackBone, Angular, Ember, or something else, that is entirely your choice.
  7. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  8. Getting started Success! Created app 'my_app' with: ! ✓ Basic

    chat demo (-m for minimal install) ✓ Javascript example code (-c if you prefer CoffeeScript) ✓ Plain HTML for views (-j if you prefer Jade) Next, run the following commands: ! cd my_app [sudo] npm install ! To start your app: ! node app.js

  9. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  10. Client side code organisation • CODE stores client side JavaScript

    files and libraries • CSS stores CSS files • STATIC stores public files like images, font files, and other assets • TEMPLATES stores HTML templates for the single page app to render on the client • VIEWS stores HTML files that are rendered from the server for the initial page
  11. This is how we load them // My SocketStream 0.3

    app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  12. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  13. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  14. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  15. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  16. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  17. // My SocketStream 0.3 app ! var http = require('http'),

    ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  18. // This file automatically gets called first by SocketStream and

    must always exist ! // Make 'ss' available to all modules and the browser console window.ss = require('socketstream'); ! ss.server.on('disconnect', function(){ console.log('Connection down :-('); }); ! ss.server.on('reconnect', function(){ console.log('Connection back up :-)'); }); ! ss.server.on('ready', function(){ ! // Wait for the DOM to finish loading jQuery(function(){ // Load app require('/app'); ! }); ! });
  19. // This file automatically gets called first by SocketStream and

    must always exist ! // Make 'ss' available to all modules and the browser console window.ss = require('socketstream'); ! ss.server.on('disconnect', function(){ console.log('Connection down :-('); }); ! ss.server.on('reconnect', function(){ console.log('Connection back up :-)'); }); ! ss.server.on('ready', function(){ ! // Wait for the DOM to finish loading jQuery(function(){ // Load app require('/app'); ! }); ! });
  20. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  21. Over the years, developers have come up with new languages

    to generate HTML, CSS, and JavaScript
  22. For HTML Templating • SS-HOGAN - supports using Twitter's Hogan.js

    • SS-COFFEEKUP - supports using CoffeeKup
  23. Setting a Templating engine // Use server-side compiled Hogan (Mustache)

    templates. Others engines available ss.client.templateEngine.use(require('ss-hogan'));
  24. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  25. Having to press F5 to reload the page in order

    to view changes to HTML/CSS/JS...
  26. In development mode, SocketStream will watch the client files for

    changes, and reload the page when they occur
  27. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  28. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  29. When you're building a single page app, you'll have a

    lot of JS files, and maybe a few CSS files
  30. But serving a HTML page with lots of these files

    can take time, and is inefficient
  31. Setting a Templating engine // Minimize and pack assets if

    you type: SS_ENV=production node app.js if (ss.env === 'production') ss.client.packAssets();
  32. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  33. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  34. SocketStream uses the following middleware by default: • compress -

    for GZipping assets • cookieParser - for handling user tracking • favicon - for serving a favicon.ico file • session - for handling sessions • static - for serving static assets
  35. SocketStream uses the following middleware by default: • compress middleware

    is loaded first, before all other middleware • static middleware is loaded last, after all other middleware
  36. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  37. We use connect’s session middleware, so authentication can be done

    with either EveryAuth, PassportJS, or you can roll your own.
  38. Via HTTP // app.js ss.http.router.on('/updateSession', function(req, res) { req.session.myVar =

    4321; res.end('req.session.myVar has been updated to', req.session.myVar); });
  39. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  40. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  41. 1 - Publishing to everyone viewing the app right now

    ss.publish.all('newMessage', message); // Broadcast the message to everyone Server // Listen out for newMessage events coming from the server ss.event.on('newMessage', function(message) { // do something with the message }); Client
  42. 2 - Sending to private channels // in a /server/rpc

    file after calling req.use('session') middleware ! req.session.channel.subscribe('disney') ! req.session.channel.unsubscribe('kids') ! req.session.channel.reset() // unsubscribes the session from every channel ! req.session.channel.list() // shows what channels are subscribed to Server (subscribe/unsubscribe the session )
  43. 2 - Sending to private channels // in a /server/rpc

    file ss.publish.channel('disney', 'chatMessage', {from: 'jerry', message: 'Has anyone seen Tom?'}); Server (publish to channel) // in a /client/code file ss.event.on('chatMessage', function(msg, channelName){ console.log('The following message was sent to the ' + channelName + ' channel:', msg); }); Client (receive channel message)
  44. 3 - Sending to users // in a /server/rpc file

    ss.publish.user('fred', 'specialOffer', 'Here is a special offer just for you!'); Server
  45. 4 - Sending to a browser tab // in a

    /server/rpc file ss.publish.socketId('254987654324567', 'justForMe', 'Just for one tab'); Server
  46. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  47. On top of RPC and PubSub, SocketStream provides you with

    a way to create custom request responders
  48. Building RPC APIs Live Reload WebSocket Management Minifying CSS/JS for

    production use Client-side code organisation Building PubSub APIs HTML / CSS / JS code preprocessing Session Management Building custom APIs on top of WS HTML Templates Web Workers Connect middleware compatibility
  49. 2 - Use HTTPS, but handle it at the load

    balancer level rather than at the app level