$30 off During Our Annual Pro Sale. View Details »

Real-time sweg

Real-time sweg

In this presentation i'll talk about sweg:

socket.io/sockjs
websockets
engine.io
google browserchannel

and why primus is yolo (your only library option) for sweg. I presented this at the first GrunnJS meetup.

Arnout Kazemier

September 24, 2014
Tweet

More Decks by Arnout Kazemier

Other Decks in Programming

Transcript

  1. sweg
    real-time

    View Slide

  2. View Slide

  3. observe it

    View Slide

  4. !
    3rdeden
    "
    3rd-eden
    with a dash

    View Slide

  5. sweg
    what does it mean to have

    View Slide

  6. sweg
    socket.io

    View Slide

  7. sweg
    sockjs

    View Slide

  8. sweg
    websocket

    View Slide

  9. sweg
    engine.io

    View Slide

  10. sweg
    google
    browserchannel

    View Slide

  11. sweg
    why do you need

    View Slide

  12. websocket
    dude
    all the things!

    View Slide

  13. Chrome 20
    Chrome for Android 18+ RFC

    View Slide

  14. Chrome 4
    older protocol

    View Slide

  15. Firefox 12
    Firefox for Android 15+ RFC

    View Slide

  16. Firefox 4
    older protocol

    View Slide

  17. Opera 12.1
    Opera Mobile 12+ RFC

    View Slide

  18. Opera 11
    older protocol behind flag

    View Slide

  19. Safari 6

    View Slide

  20. Safari 4.2
    older protocol

    View Slide

  21. Internet Explorer 10
    finally

    View Slide

  22. HTTP proxy settings in your
    network settings can cause
    a full browser crash.

    View Slide

  23. Writing to a
    can cause a full browser crash

    View Slide

  24. Pressing
    the WebSocket connection

    View Slide

  25. Firefox can create
    when you connect during

    View Slide

  26. 4G, 3G, LTE, mobile providers WTF
    ARE YOU DOING?? —

    View Slide

  27. Virus scanners such as AVG
    WebSockets.

    View Slide

  28. User, network and server firewalls
    block

    View Slide

  29. Load balancers don't understand and
    block

    View Slide

  30. new WebSocket("wss://url.io");
    doesn’t look so simple anymore

    View Slide

  31. but it has its
    use cases

    View Slide

  32. low latency
    binary
    low bandwidth
    don’t care about older browsers

    View Slide

  33. polling..
    they see me
    they hating

    View Slide

  34. Removing spinners with
    for JSONP

    View Slide

  35. Back/Forward & browse cache busting

    View Slide

  36. Client -> Server
    Server -> Client
    heartbeats

    View Slide

  37. Protocol invention

    View Slide

  38. sweg
    choosing your

    View Slide

  39. socket.io 0.9
    http://github.com/automattic/socket.io
    multiple transports
    cross domain
    invested with bugs
    poorly / not maintained / left for dead
    no message order guarantee
    dies behind firewall/virusscanners

    View Slide

  40. Cross domain
    Multiple transports
    Sending average amounts of data
    Not consumer facing

    View Slide

  41. engine.io and socket.io 1.0
    http://github.com/automattic/engine.io
    supports multiple transports
    cross domain
    upgrade instead of
    downgrade
    works behind firewalls &
    virusscanners
    not well battle tested yet
    no message order guarantee

    View Slide

  42. Quick connections
    Don’t care much about latency
    Cross browser
    Binary needed

    View Slide

  43. google’s browserchannel
    https://github.com/josephg/node-browserchannel
    https://code.google.com/p/closure-library/source/browse/closure/goog/net/browserchannel.js
    multiple transports
    client maintained by google
    message order guaranteed
    works behind firewalls &
    virusscanners
    not cross domain
    no websocket support
    coffeescript on the server for node ._.
    not well documented & relatively
    unknown

    View Slide

  44. Sending real-time updates
    Cross browser
    No need for binary data
    Medium lived connections
    Stability required over latency

    View Slide

  45. sockjs
    https://github.com/sockjs
    multiple transports 

    (tons of them)
    cross domain
    poor error handling
    no query string allowed for connect
    connection delay with firewalls
    poorly maintained
    in the way of developers

    View Slide

  46. Sendings lots of data using the most
    optimal transport
    Cross domain
    Cross browser
    No need for binary
    Long lived connected sessions

    View Slide

  47. yolo
    your only library option

    View Slide

  48. npm install primus
    primus is yolo for sweg

    View Slide

  49. Primus wraps
    real-time frameworks. So you can
    focus on building apps.

    View Slide

  50. View Slide

  51. cd your-awesome-project!
    !
    $ npm install --save primus ws!
    !
    echo "??" !
    echo “profit!”!
    !
    vim index.js

    View Slide

  52. 'use strict';!
    !
    var Primus = require("primus")!
    , server = require("http").createServer(fn)!
    , primus = new Primus(server, { transformer:"ws" });!
    !
    primus.on("connection", function connection(spark) {!
    console.log("connection received", spark.id);!
    spark.write("ohai");!
    !
    spark.on("data", function data(msg) {!
    console.log("received", msg);!
    });!
    });!
    !
    server.listen(8080);

    View Slide

  53. !
    !<br/>'use strict';!<br/>!<br/>var primus = new Primus("http://localhost:8080");!<br/>!<br/>primus.on("open", function connected() {!<br/>console.log("connection opened");!<br/>primus.write("ohai");!<br/>});!<br/>!<br/>primus.on("data", function data(msg) {!<br/>console.log(“received", msg);!<br/>});!<br/>

    View Slide

  54. var primus = new Primus(server, { !
    transformer: “sockjs" // engine.io, socket.io etc!
    });

    View Slide

  55. module.exports = require(“primus/transformer").extend({!
    server: function () {!
    // This is only exposed and ran on the server.!
    },!
    !
    client: function () {!
    // This is stringified end send/stored in the client.!
    // Can be ran on the server, if used through Node.js!
    },!
    !
    // Optional library for the front-end, assumes globals!
    library: fs.readFileSync(__dirname +"./yourclientlib.js")!
    });

    View Slide

  56. primus.on("end", function disconnected() {!
    console.log("connection ended");!
    });!
    !
    primus.end();!
    primus.write();!
    !
    fs.createReadStream(__dirname + '/index.html').pipe(spark, {!
    end: false!
    });

    View Slide

  57. var primus = new Primus(server, { !
    parser: "JSON" // JSON by default!
    });

    View Slide

  58. var primus = new Primus(server, { !
    parser: "EJSON" // or binary-pack or a third party module!
    });

    View Slide

  59. module.exports = {!
    encoder: function (data, fn) {!
    // encode data to a string.!
    },!
    !
    decoder: function (data, fn) {!
    // decode data to an object!
    },!
    !
    // Optional library for the front-end, assumes globals!
    library: fs.readFileSync(__dirname +"./yourclientlib.js")!
    };

    View Slide

  60. primus.transform('incoming', function (packet) {!
    // This would transform all incoming messages to foo;!
    packet.data = 'foo';!
    });!
    !
    primus.transform('outgoing', function (packet) {!
    // This would transform all outgoing messages to foo;!
    packet.data = 'foo';!
    });

    View Slide

  61. var primus = new Primus("http://localhost:8080", {!
    strategy: "disconnect, online"!
    });

    View Slide

  62. var Primus = require("primus")!
    , server = require("http").createServer(fn)!
    , primus = new Primus(server, { transformer:"ws" });!
    !
    primus.write("message"); // send message to all users!
    !
    primus.forEach(function (spark) {!
    // Or iterate over all connections, select the once you!
    // want and only write to those!
    !
    spark.write("message");!
    });

    View Slide

  63. // The long awaited Socket.IO 1.0 release with Primus:!
    !
    var server = require("http").createServer(fn)!
    , primus = new Primus(server, { transformer:"engine.io" });!
    !
    primus.use(“emitter","primus-emitter")!
    .use(“multiplex”, require(“primus-multiplex”))!
    .use(“primus-emitter”, "primus-rooms");

    View Slide

  64. module.exports = {!
    server: function () {!
    // This is only exposed and ran on the server.!
    },!
    !
    client: function () {!
    // This is stringified end send/stored in the client.!
    // Can be ran on the server, if used through Node.js!
    },!
    !
    // Optional library for the front-end, assumes globals!
    library: fs.readFileSync(__dirname +"./yourclientlib.js")!
    };

    View Slide

  65. var server = require("http").createServer(fn)!
    , primus = new Primus(server, { transformer:"sockjs" });!
    !
    primus.before(“session”, require(“session-parse-module”))!
    .before(“middleware-name”, "middleware-module-name");

    View Slide

  66. var server = require("http").createServer(fn)!
    , primus = new Primus(server, { transformer:"engine.io" });!
    !
    primus.on(“connection”, function middlewarish(spark, next) {!
    // do async stuff, all other “connection” events will not!
    // be called until this one completes..!
    next();!
    });

    View Slide

  67. ∞ infinite use cases

    View Slide

  68. fin
    ! 3rdeden

    View Slide