Chloe and the Realtime Web

118
Chloe and the RTW Trotter Cashion Strange Loop 2011

description

This is my Chloe talk

Transcript of Chloe and the Realtime Web

Page 1: Chloe and the Realtime Web

Chloe and the RTWTrotter Cashion

Strange Loop 2011

Page 2: Chloe and the Realtime Web

For those looking only

at slides!

Page 3: Chloe and the Realtime Web

Co-Founder

Page 4: Chloe and the Realtime Web

@cashion

Page 5: Chloe and the Realtime Web

github.com/trotter

Page 6: Chloe and the Realtime Web

Go Get It!http://github.com/mashion/chloe

Page 7: Chloe and the Realtime Web

Why?

Page 8: Chloe and the Realtime Web

Knockout!

Page 9: Chloe and the Realtime Web

simulchart.com

Page 10: Chloe and the Realtime Web

Knockout!Made me cry :-(

Page 14: Chloe and the Realtime Web

Got me thinking...

Page 15: Chloe and the Realtime Web

ChloeA realtime web-server... that doesn’t suck.

Page 16: Chloe and the Realtime Web

Cool History, Right?http://github.com/mashion/chloe

Page 17: Chloe and the Realtime Web

Usage...A Simple Chat Service

Page 18: Chloe and the Realtime Web

<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>

Page 19: Chloe and the Realtime Web

<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>

Include Chloe JS

Page 20: Chloe and the Realtime Web

<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>

Include Your JS

Page 21: Chloe and the Realtime Web

$(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>");    });  });

});

Page 22: Chloe and the Realtime Web

$(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>");    });  });

});

Instantiate Chloe

Page 23: Chloe and the Realtime Web

$(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>");    });  });

});

Connect to the Server

Page 24: Chloe and the Realtime Web

$(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>");    });  });

});

Send data to the server

Page 25: Chloe and the Realtime Web

$(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>");    });  });

});

Run this function when a message arrives

Page 26: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

Page 27: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

Get the html from earlier

Page 28: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

chloe.send(form.serialize());

Page 29: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

Ruby trick!

Page 30: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

Chloe broadcast/multicast url

Page 31: Chloe and the Realtime Web

get '/' do  erubis :indexend

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"]})  'ok'end

Send the data to Chloe

Page 32: Chloe and the Realtime Web

How It Works

Page 33: Chloe and the Realtime Web
Page 34: Chloe and the Realtime Web

Chrome

Page 35: Chloe and the Realtime Web

Chrome Server

Page 36: Chloe and the Realtime Web

Chrome Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 37: Chloe and the Realtime Web

Chrome ChloeServer *

*could be Java, Ruby, Scala, Clojure, Node...

Page 38: Chloe and the Realtime Web

Chrome ChloeGET /

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 39: Chloe and the Realtime Web

Chrome ChloeGET /

index.html

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 40: Chloe and the Realtime Web

Chrome ChloeGET /

index.html/chloe.js

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 41: Chloe and the Realtime Web

Chrome ChloeGET /

index.html/chloe.js

“Hey Everyone”

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 42: Chloe and the Realtime Web

Chrome ChloeGET /

index.html/chloe.js

“Hey Everyone”POST /updates “Hey Everyone”

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 43: Chloe and the Realtime Web

Chrome ChloeGET /

index.html/chloe.js

“Hey Everyone”POST /updates “Hey Everyone”

POST /send “Hey Everyone”

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 44: Chloe and the Realtime Web

Chrome ChloeGET /

index.html/chloe.js

“Hey Everyone”POST /updates “Hey Everyone”

POST /send “Hey Everyone”“Hey Everyone”

Server *

*could be Java, Ruby, Scala, Clojure, Node...

Page 45: Chloe and the Realtime Web

Fallbacks

WebsocketsLong polling (jsonp)Cross domain xhr - SOON!This seems to be enough for now...

Page 46: Chloe and the Realtime Web

Channels

Page 47: Chloe and the Realtime Web

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

Page 48: Chloe and the Realtime Web

chloe.connect(function () {  chloe.subscribe('chat-room-5', function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});

Channel Name

post '/updates' do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end

Page 49: Chloe and the Realtime Web

chloe.connect(function () {  chloe.subscribe('chat-room-5', function (message) {    $("#messages").prepend("<li>" + message + "</li>")  });});

Called when message arrives

post '/updates' do  uri = URI.parse("http://localhost:8901/send")  Net::HTTP.post_form(uri,       { "data" => "Hello room!", "channel" => "chat-room-5"})  "ok"end

Page 50: Chloe and the Realtime Web

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

Page 51: Chloe and the Realtime Web

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

Page 52: Chloe and the Realtime Web

What’s left for Channels

Bi-directionalityPer Channel callbacks

Page 53: Chloe and the Realtime Web

PerformanceDifficult to determine...

Page 54: Chloe and the Realtime Web

0

10

20

30

40

50

0 500 1000

17

33.5

50M

emor

y (M

B)

Sessions

Page 55: Chloe and the Realtime Web

# 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

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 56: Chloe and the Realtime Web

# 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 number of file descriptors

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 57: Chloe and the Realtime Web

# 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 transaction queue length

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 58: Chloe and the Realtime Web

# 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 size of listen queue

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 59: Chloe and the Realtime Web

# 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 incoming packet queue

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 60: Chloe and the Realtime Web

# 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=1Increase maximum receive window

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 61: Chloe and the Realtime Web

# 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=1Increase send window

Tune Your TCP Stack

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 62: Chloe and the Realtime Web

# 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

Tune Your TCP Stack

How many SYN requests to keep in memory

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 63: Chloe and the Realtime Web

# 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

Tune Your TCP Stack

Makes tcp_max_syn_backlog work

From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting

Page 64: Chloe and the Realtime Web

How much Overhead?

Page 65: Chloe and the Realtime Web

How much Overhead?

?

Page 66: Chloe and the Realtime Web

Up and Running

Page 67: Chloe and the Realtime Web

Binaries Available

Mac, Ubuntu 32bit, Ubuntu 64bitFully self-contained (Erlang included).deb and .rpm will be coming soon...

Page 68: Chloe and the Realtime Web

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

Page 69: Chloe and the Realtime Web

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

Page 70: Chloe and the Realtime Web

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

Page 71: Chloe and the Realtime Web

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

Page 72: Chloe and the Realtime Web

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

Page 73: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

Page 74: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

For XHR

Page 75: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

Callback url on your application

Page 76: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

Chloe port

Page 77: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

Where Chloe’s JavaScript Lives

Page 78: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

Directory for Logs

Page 79: Chloe and the Realtime Web

{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”} ]}

./etc/app.config

For security (not required)...

Page 80: Chloe and the Realtime Web

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})  'ok'end

Page 81: Chloe and the Realtime Web

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})  'ok'end

Page 82: Chloe and the Realtime Web

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})  'ok'end

From ./etc/app.config

Page 83: Chloe and the Realtime Web

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})  'ok'end

Concat two strings

Page 84: Chloe and the Realtime Web

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})  'ok'end

Hash them

Page 85: Chloe and the Realtime Web

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})  'ok'end Add signature to request

Page 86: Chloe and the Realtime Web

If `secret` is in your config , all requests to `/send` must be signed

Page 87: Chloe and the Realtime Web

Coming SoonImproved PerformanceBi-directional channelsPer-channel callback urlsRuntime configurationSSL Support

Page 88: Chloe and the Realtime Web

Coming Later

Improved monitoringExplore switch to mochiweb internallyClient side authentication

Page 89: Chloe and the Realtime Web

InternalsErlang Nerdery Time!

Page 90: Chloe and the Realtime Web

Session Manager

Sessions

Channel Store

YawsCallback

Transports

Page 91: Chloe and the Realtime Web

Session Manager

Sessions

Channel Store

YawsCallback

Transports

Page 92: Chloe and the Realtime Web

Session Manager

Sessions

Channel Store

YawsCallback

Transports

Page 93: Chloe and the Realtime Web

Session Manager

Sessions

Channel Store

YawsCallback

Transports

Page 94: Chloe and the Realtime Web

Session Manager

Sessions

Channel Store

YawsCallback

Transports

Page 95: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Page 96: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser

Page 97: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser New Conn

Page 98: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser New Conn Session?

Page 99: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser New Conn Session?Session Pid

Page 100: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser New Conn Session?Session Pid

Message!

Page 101: Chloe and the Realtime Web

Yaws Session ManagerWebsocket Session

Browser New Conn Session?Session Pid

Message!Server

Page 102: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Page 103: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server

Page 104: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server Sessions?

Page 105: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server Sessions?

Session Pid

Page 106: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server Sessions?

Session PidMessage!

Page 107: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server Sessions?

Session PidMessage!

Message!

Page 108: Chloe and the Realtime Web

Yaws SessionChannel Store Websocket

Server Sessions?

Session PidMessage!

BrowserMessage!

Page 109: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

Page 110: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

The message itself

Page 111: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

Version of the message protocol

Page 112: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

Four types: connect, message, channel-subscribe, poll

Page 113: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

Where the message is going

Page 114: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId}

No Idea...

Page 115: Chloe and the Realtime Web

Message Structure{ data, version, type, channel, id, sessionId} Session id for connection

Page 116: Chloe and the Realtime Web

Please Go Play With It

http://github.com/mashion/chloehttp://mashion.nethttp://trottercashion.com@cashion

Page 117: Chloe and the Realtime Web

Moved to Mountain ViewBe my friend?

Page 118: Chloe and the Realtime Web

Thank You!Good luck w/ Chloe