Your SlideShare is downloading. ×
0
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Chloe and the Realtime Web
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Chloe and the Realtime Web

1,213

Published on

This is my Chloe talk

This is my Chloe talk

Published in: Technology, Design
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,213
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
8
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Chloe and the RTW Trotter Cashion Strange Loop 2011
  • 2. For thoselooking only at slides!
  • 3. Co-Founder
  • 4. @cashion
  • 5. github.com/ trotter
  • 6. Go Get It!http://github.com/mashion/chloe
  • 7. Why?
  • 8. Knockout!
  • 9. simulchart.com
  • 10. Knockout! Made me cry :-(
  • 11. We can Haz? http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
  • 12. We can Haz? http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
  • 13. We can Haz? http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
  • 14. Got me thinking...
  • 15. ChloeA realtime web-server... that doesn’t suck.
  • 16. Cool History, Right? http://github.com/mashion/chloe
  • 17. Usage...A Simple Chat Service
  • 18. <html>  <head>    <script type="text/javascript" src="/jquery-1.6.4.min.js"></script>  <script type="text/javascript" src="http://localhost:8901/chloe.js"> </script>    <script type="text/javascript" src="/chat.js"></script>    <title>Ajax Chat</title>  </head>  <body>    <form>      <input name="message" id="message" type="text"/>      <input name="submit" type="submit" value="Send"/>    </form>    <ul id="messages"></ul>  </body></html>
  • 19. <html>  <head>    <script type="text/javascript" src="/jquery-1.6.4.min.js"></script>  <script type="text/javascript" src="http://localhost:8901/chloe.js"> </script>    <script type="text/javascript" src="/chat.js"></script>    <title>Ajax Chat</title>  </head> Include Chloe JS  <body>    <form>      <input name="message" id="message" type="text"/>      <input name="submit" type="submit" value="Send"/>    </form>    <ul id="messages"></ul>  </body></html>
  • 20. <html>  <head>    <script type="text/javascript" src="/jquery-1.6.4.min.js"></script>  <script type="text/javascript" src="http://localhost:8901/chloe.js"> </script>    <script type="text/javascript" src="/chat.js"></script>    <title>Ajax Chat</title>  </head>  <body>    <form> Include Your JS      <input name="message" id="message" type="text"/>      <input name="submit" type="submit" value="Send"/>    </form>    <ul id="messages"></ul>  </body></html>
  • 21. $(function () {  var form = $(form),      container = $(#messages);      chloe = new Chloe({host: localhost, port: 8901});  chloe.connect(function () {    form.submit(function () {      chloe.send(form.serialize());      $(#message).val();      return false;    });    chloe.onmessage(function (message) {      container.prepend("<li>" + message + "</li>");    });  });});
  • 22. $(function () {  var form = $(form),      container = $(#messages);      chloe = new Chloe({host: localhost, port: 8901});  chloe.connect(function () {    form.submit(function Instantiate () { Chloe      chloe.send(form.serialize());      $(#message).val();      return false;    });    chloe.onmessage(function (message) {      container.prepend("<li>" + message + "</li>");    });  });});
  • 23. $(function () {  var form = $(form),      container = $(#messages);      chloe = new Chloe({host: localhost, port: 8901});  chloe.connect(function () {    form.submit(function () {      chloe.send(form.serialize());      $(#message).val(); Server Connect to the      return false;    });    chloe.onmessage(function (message) {      container.prepend("<li>" + message + "</li>");    });  });});
  • 24. $(function () {  var form = $(form),      container = $(#messages);      chloe = new Chloe({host: localhost, port: 8901});  chloe.connect(function () {    form.submit(function () {      chloe.send(form.serialize());      $(#message).val();      return false;    }); Send data to the server    chloe.onmessage(function (message) {      container.prepend("<li>" + message + "</li>");    });  });});
  • 25. $(function () {  var form = $(form),      container = $(#messages);      chloe = new Chloe({host: localhost, port: 8901});  chloe.connect(function () {    form.submit(function () {      chloe.send(form.serialize());      $(#message).val();      return false; this function when Run a message arrives    });    chloe.onmessage(function (message) {      container.prepend("<li>" + message + "</li>");    });  });});
  • 26. get / do  erubis :indexendpost /updates do  data = URI.decode_www_form(request.body.read) params = Hash[data] uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]})  okend
  • 27. get / do  erubis :indexendpost /updates html from earlier Get the do  data = URI.decode_www_form(request.body.read) params = Hash[data] uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]})  okend
  • 28. get / do  erubis :indexend chloe.send(form.serialize());post /updates do  data = URI.decode_www_form(request.body.read) params = Hash[data] uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]})  okend
  • 29. get / do  erubis :indexendpost /updates do Ruby trick!  data = URI.decode_www_form(request.body.read) params = Hash[data] uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]})  okend
  • 30. get / do  erubis :indexendpost /updates do  data = URI.decode_www_form(request.body.read) params = Hash[data] uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]}) Chloe broadcast/multicast url  okend
  • 31. get / do  erubis :indexendpost /updates do  data = URI.decode_www_form(request.body.read) params = Hash[data] data to Chloe Send the uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,                {"data" => params["message"]})  okend
  • 32. How It Works
  • 33. Chrome
  • 34. Chrome Server
  • 35. Chrome Server * *could be Java, Ruby, Scala, Clojure, Node...
  • 36. Chrome Server * Chloe *could be Java, Ruby, Scala, Clojure, Node...
  • 37. Chrome Server * Chloe GET / *could be Java, Ruby, Scala, Clojure, Node...
  • 38. Chrome Server * Chloe GET / index.html *could be Java, Ruby, Scala, Clojure, Node...
  • 39. Chrome Server * Chloe GET / index.html /chloe.js *could be Java, Ruby, Scala, Clojure, Node...
  • 40. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” *could be Java, Ruby, Scala, Clojure, Node...
  • 41. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” POST /updates “Hey Everyone” *could be Java, Ruby, Scala, Clojure, Node...
  • 42. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” POST /updates “Hey Everyone” POST /send “Hey Everyone” *could be Java, Ruby, Scala, Clojure, Node...
  • 43. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” POST /updates “Hey Everyone” POST /send “Hey Everyone” “Hey Everyone” *could be Java, Ruby, Scala, Clojure, Node...
  • 44. FallbacksWebsocketsLong polling (jsonp)Cross domain xhr - SOON!This seems to be enough for now...
  • 45. Channels
  • 46. chloe.connect(function () {  chloe.subscribe(chat-room-5, function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});post /updates do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end
  • 47. Channel Namechloe.connect(function () {  chloe.subscribe(chat-room-5, function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});post /updates do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end
  • 48. chloe.connect(function () {  chloe.subscribe(chat-room-5, function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });}); Called when message arrivespost /updates do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end
  • 49. chloe.connect(function () {  chloe.subscribe(chat-room-5, function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});post /updates do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end
  • 50. chloe.connect(function () {  chloe.subscribe(chat-room-5, function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});post /updates do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end Channel for broadcast
  • 51. What’s left for Channels Bi-directionality Per Channel callbacks
  • 52. Performance Difficult to determine...
  • 53. 50 50 40 33.5Memory (MB) 30 20 17 10 0 0 500 1000 Sessions
  • 54. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 55. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# Increase number of file descriptors /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 56. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# Increase transaction queue length /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 57. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# Increase size of listen queue /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 58. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# Increase incoming packet queue /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 59. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl Increase maximum receive window -w net.ipv4.tcp_syncookies=1 From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 60. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 Increase send window From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 61. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 How many SYN requests to keep in memory From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 62. Tune Your TCP Stack# ulimit -n 65536# ifconfig eth0 txqueuelen 8192# /sbin/sysctl -w net.core.somaxconn=4096# /sbin/sysctl -w net.core.netdev_max_backlog=16384# /sbin/sysctl -w net.core.rmem_max=16777216# /sbin/sysctl -w net.core.wmem_max=16777216# /sbin/sysctl -w net.ipv4.tcp_max_syn_backlog=8192# /sbin/sysctl -w net.ipv4.tcp_syncookies=1 Makes tcp_max_syn_backlog work From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 63. How much Overhead?
  • 64. How much Overhead? ?
  • 65. Up and Running
  • 66. Binaries AvailableMac, Ubuntu 32bit, Ubuntu 64bitFully self-contained (Erlang included).deb and .rpm will be coming soon...
  • 67. It’s Easy!# wget http://bit.ly/oqyQfL# tar xzvf chloe-0.0.3-osx.tgz# cd chloe-0.0.3# ./bin/chloe start# ./bin/chloe stop
  • 68. It’s Easy!# wget http://bit.ly/oqyQfL# tar xzvf chloe-0.0.3-osx.tgz# cd chloe-0.0.3# ./bin/chloe start# ./bin/chloe stop
  • 69. It’s Easy!# wget http://bit.ly/oqyQfL# tar xzvf chloe-0.0.3-osx.tgz# cd chloe-0.0.3# ./bin/chloe start# ./bin/chloe stop
  • 70. It’s Easy!# wget http://bit.ly/oqyQfL# tar xzvf chloe-0.0.3-osx.tgz# cd chloe-0.0.3# ./bin/chloe start# ./bin/chloe stop
  • 71. It’s Easy!# wget http://bit.ly/oqyQfL# tar xzvf chloe-0.0.3-osx.tgz# cd chloe-0.0.3# ./bin/chloe start# ./bin/chloe stop
  • 72. ./etc/app.config{chloe, [ {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 73. ./etc/app.config{chloe, For XHR [ {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 74. ./etc/app.config{chloe, [ Callback url on your application {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 75. ./etc/app.config{chloe, [ Chloe port {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 76. ./etc/app.config{chloe, [ Where Chloe’s JavaScript Lives {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 77. ./etc/app.config{chloe, [ {application_server, "http://localhost:4567"}, Directory for Logs {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]}
  • 78. ./etc/app.config{chloe, [ {application_server, "http://localhost:4567"}, {application_server_url, "http://localhost:4567/updates"}, {port, 8901}, {doc_root, "./public"}, {log_dir, "/var/log/chloe"}, {secret, “SEKRET PASSFRASE”} ]} For security (not required)...
  • 79. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend
  • 80. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend
  • 81. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do From ./etc/app.config  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend
  • 82. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do Concat t wo strings  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend
  • 83. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do Hash them  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend
  • 84. Signing RequestsSECRET = "SEKRET PASSFRASE”post /updates do  data = URI.decode_www_form(request.body.read) message = Hash[data]["message"] sig = Digest::MD5.hexdigest(message + SECRET) uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,             {"data" => message, "sig" => sig})  okend Add signature to request
  • 85. If `secret` is in yourconfig, all requests to`/send` must be signed
  • 86. Coming SoonImproved PerformanceBi-directional channelsPer-channel callback urlsRuntime configurationSSL Support
  • 87. Coming LaterImproved monitoringExplore switch to mochiweb internallyClient side authentication
  • 88. InternalsErlang Nerdery Time!
  • 89. Session Manager TransportsYaws Callback Sessions Channel Store
  • 90. Session Manager TransportsYaws Callback Sessions Channel Store
  • 91. Session Manager TransportsYaws Callback Sessions Channel Store
  • 92. Session Manager TransportsYaws Callback Sessions Channel Store
  • 93. Session Manager TransportsYaws Callback Sessions Channel Store
  • 94. SessionYaws Websocket Manager Session
  • 95. Session Yaws Websocket Manager SessionBrowser
  • 96. Session Yaws Websocket Manager SessionBrowser New Conn
  • 97. Session Yaws Websocket Manager SessionBrowser New Conn Session?
  • 98. Session Yaws Websocket Manager SessionBrowser New Conn Session? Session Pid
  • 99. Session Yaws Websocket Manager SessionBrowser New Conn Session? Session Pid Message!
  • 100. Session Yaws Websocket Manager SessionBrowser New Conn Session? Session Pid Message! Server
  • 101. ChannelYaws Store Session Websocket
  • 102. Channel Yaws Store Session WebsocketServer
  • 103. Channel Yaws Store Session WebsocketServer Sessions?
  • 104. Channel Yaws Store Session WebsocketServer Sessions? Session Pid
  • 105. Channel Yaws Store Session WebsocketServer Sessions? Session Pid Message!
  • 106. Channel Yaws Store Session WebsocketServer Sessions? Session Pid Message! Message!
  • 107. Channel Yaws Store Session WebsocketServer Sessions? Session Pid Message! Message! Browser
  • 108. Message Structure{ data, version, type, channel, id, sessionId}
  • 109. Message Structure{ data, version, type,The message itself channel, id, sessionId}
  • 110. Message Structure{ data, version, type, Version of the message protocol channel, id, sessionId}
  • 111. Message Structure{ data, version, type, channel, Four types: connect, message, id, channel-subscribe, poll sessionId}
  • 112. Message Structure{ data, version, type, channel, id, sessionId the message is going Where}
  • 113. Message Structure{ data, version, type, channel, id, sessionId} No Idea...
  • 114. Message Structure{ data, version, type, channel, id, sessionId} Session id for connection
  • 115. Please Go Play With It http://github.com/mashion/chloe http://mashion.net http://trottercashion.com @cashion
  • 116. Moved to Mountain View Be my friend?
  • 117. Thank You! Good luck w/ Chloe

×