SlideShare uma empresa Scribd logo
1 de 118
Baixar para ler offline
Chloe and the RTW
      Trotter Cashion
    Strange Loop 2011
For those
looking only
  at slides!
Co-Founder
@cashion
github.com/
   trotter
Go Get It!
http://github.com/mashion/chloe
Why?
Knockout!
simulchart.com
Knockout!
 Made me cry :-(
We can Haz?
 http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
We can Haz?
 http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
We can Haz?
 http://utterinsanity.files.wordpress.com/2008/09/funny-pictures-cat-drives-an-invisible-racecar.jpg%3Fw%3D497%26h%3D318
Got me thinking...
Chloe
A realtime web-server... that doesn’t suck.
Cool History, Right?
  http://github.com/mashion/chloe
Usage...
A Simple Chat Service
<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>
<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>
<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>
$(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>");
    });
  });

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

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

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

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

});
get '/' do
  erubis :index
end

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 '/' do
  erubis :index
end

post '/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"]})
  'ok'
end
get '/' do
  erubis :index
end
                     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"]})
  'ok'
end
get '/' do
  erubis :index
end

post '/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"]})
  'ok'
end
get '/' do
  erubis :index
end

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"]})
        Chloe broadcast/multicast url
  'ok'
end
get '/' do
  erubis :index
end

post '/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"]})
  'ok'
end
How It Works
Chrome
Chrome   Server
Chrome          Server *




         *could be Java, Ruby, Scala, Clojure, Node...
Chrome          Server *                 Chloe




         *could be Java, Ruby, Scala, Clojure, Node...
Chrome            Server *                 Chloe
         GET /




           *could be Java, Ruby, Scala, Clojure, Node...
Chrome                Server *               Chloe
           GET /
         index.html




             *could be Java, Ruby, Scala, Clojure, Node...
Chrome                Server *                Chloe
           GET /
         index.html
          /chloe.js




              *could be Java, Ruby, Scala, Clojure, Node...
Chrome                Server *                Chloe
           GET /
         index.html
          /chloe.js
     “Hey Everyone”




              *could be Java, Ruby, Scala, Clojure, Node...
Chrome                Server *                Chloe
           GET /
         index.html
          /chloe.js
     “Hey Everyone”
                      POST /updates “Hey Everyone”




              *could be Java, Ruby, Scala, Clojure, Node...
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...
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...
Fallbacks

Websockets
Long polling (jsonp)
Cross domain xhr - SOON!
This seems to be enough for now...
Channels
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 Name
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
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
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
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
What’s left for Channels


 Bi-directionality
 Per Channel callbacks
Performance
 Difficult to determine...
50
                                          50



              40


                                 33.5
Memory (MB)




              30


              20
                       17

              10


              0
                   0         500        1000
                            Sessions
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
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
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
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
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
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
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
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
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
How much Overhead?
How much Overhead?


       ?
Up and Running
Binaries Available

Mac, Ubuntu 32bit, Ubuntu 64bit
Fully self-contained (Erlang included)
.deb and .rpm will be coming soon...
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
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
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
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
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
./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”}
  ]}
./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”}
  ]}
./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”}
  ]}
./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”}
  ]}
./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”}
  ]}
./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”}
  ]}
./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)...
Signing Requests
SECRET = "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
Signing Requests
SECRET = "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
Signing Requests
SECRET = "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})
  'ok'
end
Signing Requests
SECRET = "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})
  'ok'
end
Signing Requests
SECRET = "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})
  'ok'
end
Signing Requests
SECRET = "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
If `secret` is in your
config, all requests to
`/send` must be signed
Coming Soon
Improved Performance
Bi-directional channels
Per-channel callback urls
Runtime configuration
SSL Support
Coming Later

Improved monitoring
Explore switch to mochiweb internally
Client side authentication
Internals
Erlang Nerdery Time!
Session Manager
       Transports
Yaws
        Callback
                    Sessions




                    Channel Store
Session Manager
       Transports
Yaws
        Callback
                    Sessions




                    Channel Store
Session Manager
       Transports
Yaws
        Callback
                    Sessions




                    Channel Store
Session Manager
       Transports
Yaws
        Callback
                    Sessions




                    Channel Store
Session Manager
       Transports
Yaws
        Callback
                    Sessions




                    Channel Store
Session
Yaws   Websocket
                   Manager   Session
Session
     Yaws   Websocket
                        Manager   Session
Browser
Session
     Yaws      Websocket
                           Manager   Session
Browser
          New Conn
Session
     Yaws      Websocket
                            Manager   Session
Browser
          New Conn
                      Session?
Session
     Yaws      Websocket
                             Manager   Session
Browser
          New Conn
                      Session?
                     Session Pid
Session
     Yaws      Websocket
                             Manager   Session
Browser
          New Conn
                      Session?
                     Session Pid

                            Message!
Session
     Yaws      Websocket
                             Manager   Session
Browser
          New Conn
                      Session?
                     Session Pid

                            Message!
                                            Server
Channel
Yaws    Store    Session   Websocket
Channel
     Yaws    Store    Session   Websocket

Server
Channel
     Yaws        Store    Session   Websocket

Server
         Sessions?
Channel
     Yaws         Store    Session   Websocket

Server
         Sessions?
         Session Pid
Channel
     Yaws         Store    Session   Websocket

Server
         Sessions?
         Session Pid
                Message!
Channel
     Yaws         Store    Session    Websocket

Server
         Sessions?
         Session Pid
                Message!
                                Message!
Channel
     Yaws         Store    Session    Websocket

Server
         Sessions?
         Session Pid
                Message!
                                Message!
                                           Browser
Message Structure
{ data,
  version,
  type,
  channel,
  id,
  sessionId
}
Message Structure
{ data,
  version,
  type,The message itself
  channel,
  id,
  sessionId
}
Message Structure
{ data,
  version,
  type,
        Version of the message protocol
  channel,
  id,
  sessionId
}
Message Structure
{ data,
  version,
  type,
  channel,
        Four types: connect, message,
  id,               channel-subscribe, poll
  sessionId
}
Message Structure
{ data,
  version,
  type,
  channel,
  id,
  sessionId the message is going
        Where
}
Message Structure
{ data,
  version,
  type,
  channel,
  id,
  sessionId
}       No Idea...
Message Structure
{ data,
  version,
  type,
  channel,
  id,
  sessionId
}
       Session id for connection
Please Go Play With It

 http://github.com/mashion/chloe
 http://mashion.net
 http://trottercashion.com
 @cashion
Moved to Mountain View
        Be my friend?
Thank You!
 Good luck w/ Chloe

Mais conteúdo relacionado

Mais procurados

Consul ou comment bien tirer sur l’élastique
 Consul ou comment bien tirer sur l’élastique Consul ou comment bien tirer sur l’élastique
Consul ou comment bien tirer sur l’élastiqueNicolas Ledez
 
Async. and Realtime Geo Applications with Node.js
Async. and Realtime Geo Applications with Node.jsAsync. and Realtime Geo Applications with Node.js
Async. and Realtime Geo Applications with Node.jsShoaib Burq
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on railsPriceen
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Tomasz Dziuda
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingSteve Rhoades
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestMyles Braithwaite
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challengervanphp
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonLuciano Mammino
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Ryan Weaver
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleIan Barber
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Kenji Tanaka
 

Mais procurados (20)

Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Consul ou comment bien tirer sur l’élastique
 Consul ou comment bien tirer sur l’élastique Consul ou comment bien tirer sur l’élastique
Consul ou comment bien tirer sur l’élastique
 
Async. and Realtime Geo Applications with Node.js
Async. and Realtime Geo Applications with Node.jsAsync. and Realtime Geo Applications with Node.js
Async. and Realtime Geo Applications with Node.js
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on rails
 
A Gentle Introduction to Event Loops
A Gentle Introduction to Event LoopsA Gentle Introduction to Event Loops
A Gentle Introduction to Event Loops
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux Fest
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challenger
 
Play á la Rails
Play á la RailsPlay á la Rails
Play á la Rails
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made Simple
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 

Destaque

LXC, Docker, and the future of software delivery | LinuxCon 2013
LXC, Docker, and the future of software delivery | LinuxCon 2013LXC, Docker, and the future of software delivery | LinuxCon 2013
LXC, Docker, and the future of software delivery | LinuxCon 2013dotCloud
 
Blazes: coordination analysis for distributed programs
Blazes: coordination analysis for distributed programsBlazes: coordination analysis for distributed programs
Blazes: coordination analysis for distributed programspalvaro
 
Hyperdex - A closer look
Hyperdex - A closer lookHyperdex - A closer look
Hyperdex - A closer lookDECK36
 
Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010Rusty Klophaus
 
ElasticSearch - index server used as a document database
ElasticSearch - index server used as a document databaseElasticSearch - index server used as a document database
ElasticSearch - index server used as a document databaseRobert Lujo
 
(Functional) reactive programming (@pavlobaron)
(Functional) reactive programming (@pavlobaron)(Functional) reactive programming (@pavlobaron)
(Functional) reactive programming (@pavlobaron)Pavlo Baron
 
Complex Legacy System Archiving/Data Retention with MongoDB and Xquery
Complex Legacy System Archiving/Data Retention with MongoDB and XqueryComplex Legacy System Archiving/Data Retention with MongoDB and Xquery
Complex Legacy System Archiving/Data Retention with MongoDB and XqueryDATAVERSITY
 
Spring Cleaning for Your Smartphone
Spring Cleaning for Your SmartphoneSpring Cleaning for Your Smartphone
Spring Cleaning for Your SmartphoneLookout
 
Web-Oriented Architecture (WOA)
Web-Oriented Architecture (WOA)Web-Oriented Architecture (WOA)
Web-Oriented Architecture (WOA)thetechnicalweb
 
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
In Pursuit of the Holy Grail: Building Isomorphic JavaScript AppsIn Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
In Pursuit of the Holy Grail: Building Isomorphic JavaScript AppsSpike Brehm
 
Scalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBScalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBWilliam Candillon
 
Interoperability With RabbitMq
Interoperability With RabbitMqInteroperability With RabbitMq
Interoperability With RabbitMqAlvaro Videla
 
Erlang plus BDB: Disrupting the Conventional Web Wisdom
Erlang plus BDB: Disrupting the Conventional Web WisdomErlang plus BDB: Disrupting the Conventional Web Wisdom
Erlang plus BDB: Disrupting the Conventional Web Wisdomguest3933de
 
Shrinking the Haystack" using Solr and OpenNLP
Shrinking the Haystack" using Solr and OpenNLPShrinking the Haystack" using Solr and OpenNLP
Shrinking the Haystack" using Solr and OpenNLPlucenerevolution
 
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...C4Media
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptIngvar Stepanyan
 
Erlang as a cloud citizen, a fractal approach to throughput
Erlang as a cloud citizen, a fractal approach to throughputErlang as a cloud citizen, a fractal approach to throughput
Erlang as a cloud citizen, a fractal approach to throughputPaolo Negri
 
Pregel: A System for Large-Scale Graph Processing
Pregel: A System for Large-Scale Graph ProcessingPregel: A System for Large-Scale Graph Processing
Pregel: A System for Large-Scale Graph ProcessingChris Bunch
 

Destaque (20)

LXC, Docker, and the future of software delivery | LinuxCon 2013
LXC, Docker, and the future of software delivery | LinuxCon 2013LXC, Docker, and the future of software delivery | LinuxCon 2013
LXC, Docker, and the future of software delivery | LinuxCon 2013
 
Brunch With Coffee
Brunch With CoffeeBrunch With Coffee
Brunch With Coffee
 
Blazes: coordination analysis for distributed programs
Blazes: coordination analysis for distributed programsBlazes: coordination analysis for distributed programs
Blazes: coordination analysis for distributed programs
 
Hyperdex - A closer look
Hyperdex - A closer lookHyperdex - A closer look
Hyperdex - A closer look
 
Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010
 
ElasticSearch - index server used as a document database
ElasticSearch - index server used as a document databaseElasticSearch - index server used as a document database
ElasticSearch - index server used as a document database
 
(Functional) reactive programming (@pavlobaron)
(Functional) reactive programming (@pavlobaron)(Functional) reactive programming (@pavlobaron)
(Functional) reactive programming (@pavlobaron)
 
Complex Legacy System Archiving/Data Retention with MongoDB and Xquery
Complex Legacy System Archiving/Data Retention with MongoDB and XqueryComplex Legacy System Archiving/Data Retention with MongoDB and Xquery
Complex Legacy System Archiving/Data Retention with MongoDB and Xquery
 
Spring Cleaning for Your Smartphone
Spring Cleaning for Your SmartphoneSpring Cleaning for Your Smartphone
Spring Cleaning for Your Smartphone
 
NkSIP: The Erlang SIP application server
NkSIP: The Erlang SIP application serverNkSIP: The Erlang SIP application server
NkSIP: The Erlang SIP application server
 
Web-Oriented Architecture (WOA)
Web-Oriented Architecture (WOA)Web-Oriented Architecture (WOA)
Web-Oriented Architecture (WOA)
 
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
In Pursuit of the Holy Grail: Building Isomorphic JavaScript AppsIn Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
 
Scalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBScalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDB
 
Interoperability With RabbitMq
Interoperability With RabbitMqInteroperability With RabbitMq
Interoperability With RabbitMq
 
Erlang plus BDB: Disrupting the Conventional Web Wisdom
Erlang plus BDB: Disrupting the Conventional Web WisdomErlang plus BDB: Disrupting the Conventional Web Wisdom
Erlang plus BDB: Disrupting the Conventional Web Wisdom
 
Shrinking the Haystack" using Solr and OpenNLP
Shrinking the Haystack" using Solr and OpenNLPShrinking the Haystack" using Solr and OpenNLP
Shrinking the Haystack" using Solr and OpenNLP
 
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...
Scaling Gilt: from Monolithic Ruby Application to Distributed Scala Micro-Ser...
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Erlang as a cloud citizen, a fractal approach to throughput
Erlang as a cloud citizen, a fractal approach to throughputErlang as a cloud citizen, a fractal approach to throughput
Erlang as a cloud citizen, a fractal approach to throughput
 
Pregel: A System for Large-Scale Graph Processing
Pregel: A System for Large-Scale Graph ProcessingPregel: A System for Large-Scale Graph Processing
Pregel: A System for Large-Scale Graph Processing
 

Semelhante a Chloe and the Realtime Web

Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Workhorse Computing
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
Kamailio and VoIP Wild World
Kamailio and VoIP Wild WorldKamailio and VoIP Wild World
Kamailio and VoIP Wild World2600Hz
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStackBram Vogelaar
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webclkao
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Ismael Celis
 
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023Thijs Feryn
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rackdanwrong
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™Nicola Iarocci
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.xYiguang Hu
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and PythonPiXeL16
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developersAndrew Eddie
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 

Semelhante a Chloe and the Realtime Web (20)

Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
Kamailio and VoIP Wild World
Kamailio and VoIP Wild WorldKamailio and VoIP Wild World
Kamailio and VoIP Wild World
 
Kamailio and VoIP Wild World
Kamailio and VoIP Wild WorldKamailio and VoIP Wild World
Kamailio and VoIP Wild World
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
Node.js - A Quick Tour
Node.js - A Quick TourNode.js - A Quick Tour
Node.js - A Quick Tour
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rack
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 

Último

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 

Último (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 

Chloe and the Realtime Web

  • 1. Chloe and the RTW Trotter Cashion Strange Loop 2011
  • 5. github.com/ trotter
  • 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
  • 15. Chloe A realtime web-server... that doesn’t suck.
  • 16. Cool History, Right? http://github.com/mashion/chloe
  • 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 :index end 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
  • 27. get '/' do   erubis :index end post '/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"]})   'ok' end
  • 28. get '/' do   erubis :index end 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"]})   'ok' end
  • 29. get '/' do   erubis :index end post '/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"]})   'ok' end
  • 30. get '/' do   erubis :index end 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"]}) Chloe broadcast/multicast url   'ok' end
  • 31. get '/' do   erubis :index end post '/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"]})   'ok' end
  • 33.
  • 35. Chrome Server
  • 36. Chrome Server * *could be Java, Ruby, Scala, Clojure, Node...
  • 37. Chrome Server * Chloe *could be Java, Ruby, Scala, Clojure, Node...
  • 38. Chrome Server * Chloe GET / *could be Java, Ruby, Scala, Clojure, Node...
  • 39. Chrome Server * Chloe GET / index.html *could be Java, Ruby, Scala, Clojure, Node...
  • 40. Chrome Server * Chloe GET / index.html /chloe.js *could be Java, Ruby, Scala, Clojure, Node...
  • 41. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” *could be Java, Ruby, Scala, Clojure, Node...
  • 42. Chrome Server * Chloe GET / index.html /chloe.js “Hey Everyone” POST /updates “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” *could be Java, Ruby, Scala, Clojure, Node...
  • 44. 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...
  • 45. Fallbacks Websockets Long polling (jsonp) Cross domain xhr - SOON! This seems to be enough for now...
  • 47. 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
  • 48. Channel Name 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
  • 49. 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
  • 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
  • 51. 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
  • 52. What’s left for Channels Bi-directionality Per Channel callbacks
  • 53. Performance Difficult to determine...
  • 54. 50 50 40 33.5 Memory (MB) 30 20 17 10 0 0 500 1000 Sessions
  • 55. 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
  • 56. 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
  • 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 # 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
  • 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 # 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
  • 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 # 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
  • 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 Increase maximum receive window -w net.ipv4.tcp_syncookies=1 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 Increase send window 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 How many SYN requests to keep in memory From cometd: http://cometd.org/documentation/2.x/howtos/loadtesting
  • 63. 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
  • 67. Binaries Available Mac, Ubuntu 32bit, Ubuntu 64bit Fully self-contained (Erlang included) .deb and .rpm will be coming soon...
  • 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. 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
  • 73. ./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”} ]}
  • 74. ./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”} ]}
  • 75. ./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”} ]}
  • 76. ./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”} ]}
  • 77. ./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”} ]}
  • 78. ./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”} ]}
  • 79. ./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)...
  • 80. Signing Requests SECRET = "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
  • 81. Signing Requests SECRET = "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
  • 82. Signing Requests SECRET = "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})   'ok' end
  • 83. Signing Requests SECRET = "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})   'ok' end
  • 84. Signing Requests SECRET = "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})   'ok' end
  • 85. Signing Requests SECRET = "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
  • 86. If `secret` is in your config, all requests to `/send` must be signed
  • 87. Coming Soon Improved Performance Bi-directional channels Per-channel callback urls Runtime configuration SSL Support
  • 88. Coming Later Improved monitoring Explore switch to mochiweb internally Client side authentication
  • 90. Session Manager Transports Yaws Callback Sessions Channel Store
  • 91. Session Manager Transports Yaws Callback Sessions Channel Store
  • 92. Session Manager Transports Yaws Callback Sessions Channel Store
  • 93. Session Manager Transports Yaws Callback Sessions Channel Store
  • 94. Session Manager Transports Yaws Callback Sessions Channel Store
  • 95. Session Yaws Websocket Manager Session
  • 96. Session Yaws Websocket Manager Session Browser
  • 97. Session Yaws Websocket Manager Session Browser New Conn
  • 98. Session Yaws Websocket Manager Session Browser New Conn Session?
  • 99. Session Yaws Websocket Manager Session Browser New Conn Session? Session Pid
  • 100. Session Yaws Websocket Manager Session Browser New Conn Session? Session Pid Message!
  • 101. Session Yaws Websocket Manager Session Browser New Conn Session? Session Pid Message! Server
  • 102. Channel Yaws Store Session Websocket
  • 103. Channel Yaws Store Session Websocket Server
  • 104. Channel Yaws Store Session Websocket Server Sessions?
  • 105. Channel Yaws Store Session Websocket Server Sessions? Session Pid
  • 106. Channel Yaws Store Session Websocket Server Sessions? Session Pid Message!
  • 107. Channel Yaws Store Session Websocket Server Sessions? Session Pid Message! Message!
  • 108. Channel Yaws Store Session Websocket Server Sessions? Session Pid Message! Message! Browser
  • 109. Message Structure { data, version, type, channel, id, sessionId }
  • 110. Message Structure { data, version, type,The message itself channel, id, sessionId }
  • 111. Message Structure { data, version, type, Version of the message protocol channel, id, sessionId }
  • 112. Message Structure { data, version, type, channel, Four types: connect, message, id, channel-subscribe, poll sessionId }
  • 113. Message Structure { data, version, type, channel, id, sessionId the message is going Where }
  • 114. Message Structure { data, version, type, channel, id, sessionId } No Idea...
  • 115. Message Structure { data, version, type, channel, id, sessionId } Session id for connection
  • 116. Please Go Play With It http://github.com/mashion/chloe http://mashion.net http://trottercashion.com @cashion
  • 117. Moved to Mountain View Be my friend?
  • 118. Thank You! Good luck w/ Chloe