$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

  2. None
  3. observe it

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

  5. sweg what does it mean to have

  6. sweg socket.io

  7. sweg sockjs

  8. sweg websocket

  9. sweg engine.io

  10. sweg google browserchannel

  11. sweg why do you need

  12. websocket dude all the things!

  13. Chrome 20 Chrome for Android 18+ RFC

  14. Chrome 4 older protocol

  15. Firefox 12 Firefox for Android 15+ RFC

  16. Firefox 4 older protocol

  17. Opera 12.1 Opera Mobile 12+ RFC

  18. Opera 11 older protocol behind flag

  19. Safari 6

  20. Safari 4.2 older protocol

  21. Internet Explorer 10 finally

  22. HTTP proxy settings in your network settings can cause a

    full browser crash.
  23. Writing to a can cause a full browser crash

  24. Pressing the WebSocket connection

  25. Firefox can create when you connect during

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

  27. Virus scanners such as AVG WebSockets.

  28. User, network and server firewalls block

  29. Load balancers don't understand and block

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

  31. but it has its use cases

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

  33. polling.. they see me they hating

  34. Removing spinners with <iframes> for JSONP

  35. Back/Forward & browse cache busting

  36. Client -> Server Server -> Client heartbeats

  37. Protocol invention

  38. sweg choosing your

  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
  40. Cross domain Multiple transports Sending average amounts of data Not

    consumer facing
  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
  42. Quick connections Don’t care much about latency Cross browser Binary

    needed
  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
  44. Sending real-time updates Cross browser No need for binary data

    Medium lived connections Stability required over latency
  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
  46. Sendings lots of data using the most optimal transport Cross

    domain Cross browser No need for binary Long lived connected sessions
  47. yolo your only library option

  48. npm install primus primus is yolo for sweg

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

    apps.
  50. None
  51. cd your-awesome-project! ! $ npm install --save primus ws! !

    echo "??" ! echo “profit!”! ! vim index.js
  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);
  53. <script src="http://localhost:8080/primus/primus.js"></script>! <script>! 'use strict';! ! var primus = new

    Primus("http://localhost:8080");! ! primus.on("open", function connected() {! console.log("connection opened");! primus.write("ohai");! });! ! primus.on("data", function data(msg) {! console.log(“received", msg);! });! </script>
  54. var primus = new Primus(server, { ! transformer: “sockjs" //

    engine.io, socket.io etc! });
  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")! });
  56. primus.on("end", function disconnected() {! console.log("connection ended");! });! ! primus.end();! primus.write();!

    ! fs.createReadStream(__dirname + '/index.html').pipe(spark, {! end: false! });
  57. var primus = new Primus(server, { ! parser: "JSON" //

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

    or binary-pack or a third party module! });
  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")! };
  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';! });
  61. var primus = new Primus("http://localhost:8080", {! strategy: "disconnect, online"! });

  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");! });
  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");
  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")! };
  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");
  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();! });
  67. ∞ infinite use cases

  68. fin ! 3rdeden