SlideShare a Scribd company logo
AnyMQ, Hippie
 and the real-time web

       YAPC::Asia 2010 Tokyo
   Chia-liang Kao clkao@clkao.org
clkao
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie:Pipe
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
Plack: Web
PSGI
$env




[
       '200',
       [ 'Content-Type' => 'text/plain' ],
       [ "Hello World" ],
]
$env->{PATH_INFO}


$env




[
       '200',
       [ 'Content-Type' => 'text/plain' ],
       [ "Hello World" ],
]
$env->{PATH_INFO}

       Plack::Request->new($env)->path_info
$env




[
       '200',
       [ 'Content-Type' => 'text/plain' ],
       [ "Hello World" ],
]
$env
                 Streaming Interface
sub {
   my $responder = shift;
   my $writer = $responder->([
          '200',
          [ 'Content-Type' => 'text/plain' ]);
   # later, of in a callback
   $writer->write(“Hello world!”);
   $writer->close();
}
$env
       Streaming Interface(Cont.)
sub {
   my $responder = shift;
   my $writer = $responder->([
           '200',
           [ 'Content-Type' => 'text/plain' ]);
   # later, of in a callback
   my $w; $w = AnyEvent->timer(after => 3,
      cb => sub {
        $writer->write(“Hello world!”);
        $writer->close();
      });
}
CGI.pm

! ☠! ☠! ☠
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
AnyEvent
•
•
AnyEvent
•
•
    use AnyEvent::HTTP;

    http_get "http://yapc.asia/",
                  sub { print $_[1] };
    # do something else
POE
sub POE::Kernel::ASSERT_DEFAULT () { 1 }

use HTTP::Request;
use POE qw(Component::Client::HTTP);

POE::Component::Client::HTTP->spawn(
  Alias     => 'ua',                   # defaults to 'weeble'
  Timeout   => 20,                     # defaults to 180 seconds
);

POE::Session->create(
  inline_states => {
    _start => sub {
      POE::Kernel->post(
        'ua',         # posts to the 'ua' alias
        'request',    # posts to ua's 'request' state
        'response', # which of our states will receive the response
        HTTP::Request->new(GET => “http://osdc.tw”),
      );
    },
    _stop => sub {},
    response => &response_handler,
  },
);

POE::Kernel->run();
exit;

sub response_handler {
  my ($request_packet, $response_packet) = @_[ARG0, ARG1];
  my $request_object = $request_packet->[0];
  my $response_object = $response_packet->[0];
}
☹
use AnyEvent::HTTP;

http_get "http://yapc.asia/",
              sub { print $_[1] };




      ☺
AnyEvent::*
  AnyEvent-AIO AnyEvent-APNS AnyEvent-Atom-Stream AnyEvent-BDB AnyEvent-
  Beanstalk AnyEvent-Connection AnyEvent-CouchDB AnyEvent-DBI AnyEvent-DBI-
 Abstract AnyEvent-EditText AnyEvent-FCGI AnyEvent-FCP AnyEvent-FIFO AnyEvent-
   FastPing AnyEvent-Feed AnyEvent-Filesys-Notify AnyEvent-FriendFeed-Realtime
    AnyEvent-GPSD AnyEvent-Gearman AnyEvent-Gearman AnyEvent-Gmail-Feed
AnyEvent-HTTP AnyEvent-HTTP-MXHR AnyEvent-HTTPD AnyEvent-I3 AnyEvent-IRC
 AnyEvent-JSONRPC-Lite AnyEvent-Kanye AnyEvent-MP AnyEvent-MPRPC AnyEvent-
 Memcached AnyEvent-Mojo AnyEvent-Monitor-CPU AnyEvent-Pcap AnyEvent-Plurk
    AnyEvent-Postfix-Logs AnyEvent-RTPG AnyEvent-Redis AnyEvent-RetryTimer
AnyEvent-ReverseHTTP AnyEvent-Riak AnyEvent-Run AnyEvent-SCGI AnyEvent-SMTP
    AnyEvent-SNMP AnyEvent-Subprocess AnyEvent-Superfeedr AnyEvent-Twitter
AnyEvent-Twitter-Stream AnyEvent-Watchdog AnyEvent-Worker AnyEvent-XMLRPC
                         AnyEvent-XMPP AnyEvent-mDNS
AnyMQ
AnyMQ
• Tatsumaki::MessageQueue
AnyMQ
• Tatsumaki::MessageQueue
AnyMQ
• Tatsumaki::MessageQueue
AnyMQ
• Tatsumaki::MessageQueue
•
AnyMQ
• Tatsumaki::MessageQueue
•

• Moose
AnyMQ
• Tatsumaki::MessageQueue
•

• Moose
AnyMQ
• Tatsumaki::MessageQueue
•

• Moose
AnyMQ

my $bus = AnyMQ->new;
my $topic = $bus->topic("Foo");

my $sub = $bus->new_listener($topic);
$sub->poll(sub { my $msg = shift; })

$topic->publish($msg)
AnyMQ with AMQP
my $bus = AnyMQ->new_with_traits
          ( traits => [ ‘AMQP’],
            # host => ..., port => ..);
my $topic = $bus->topic("Foo");

my $sub = $bus->new_listener($topic);
$sub->poll(sub { my $msg = shift; })

$topic->publish($msg)
AnyMQ with AMQP
AnyMQ with AMQP
my $bus = AnyMQ->new_with_traits           my $bus = AnyMQ->new_with_traits
          ( traits => [ ‘AMQP’],                     ( traits => [ ‘AMQP’],
            # host => ..., port => ..);                # host => ..., port => ..);
my $topic = $bus->topic("Foo");            my $topic = $bus->topic("Foo");

my $sub = $bus->new_listener($topic);      my $sub = $bus->new_listener($topic);
$sub->poll(sub { my $msg = shift; })       $sub->poll(sub { my $msg = shift; })

$topic->publish($msg)                      $topic->publish($msg)




 my $bus = AnyMQ->new_with_traits          my $bus = AnyMQ->new_with_traits
           ( traits => [ ‘AMQP’],                    ( traits => [ ‘AMQP’],
             # host => ..., port => ..);               # host => ..., port => ..);
 my $topic = $bus->topic("Foo");           my $topic = $bus->topic("Foo");

 my $sub = $bus->new_listener($topic);     my $sub = $bus->new_listener($topic);
 $sub->poll(sub { my $msg = shift; })      $sub->poll(sub { my $msg = shift; })

 $topic->publish($msg)                     $topic->publish($msg)
AnyMQ with AMQP
my $bus = AnyMQ->new_with_traits                  my $bus = AnyMQ->new_with_traits
          ( traits => [ ‘AMQP’],                            ( traits => [ ‘AMQP’],
            # host => ..., port => ..);                       # host => ..., port => ..);
my $topic = $bus->topic("Foo");                   my $topic = $bus->topic("Foo");

my $sub = $bus->new_listener($topic);             my $sub = $bus->new_listener($topic);
$sub->poll(sub { my $msg = shift; })              $sub->poll(sub { my $msg = shift; })

$topic->publish($msg)                             $topic->publish($msg)
                                         AMQP
                                         Server
 my $bus = AnyMQ->new_with_traits                 my $bus = AnyMQ->new_with_traits
           ( traits => [ ‘AMQP’],                           ( traits => [ ‘AMQP’],
             # host => ..., port => ..);                      # host => ..., port => ..);
 my $topic = $bus->topic("Foo");                  my $topic = $bus->topic("Foo");

 my $sub = $bus->new_listener($topic);            my $sub = $bus->new_listener($topic);
 $sub->poll(sub { my $msg = shift; })             $sub->poll(sub { my $msg = shift; })

 $topic->publish($msg)                            $topic->publish($msg)
!
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
Comet


-
Comet
The word comet came to English by way of the Latin word cometes. This word, in turn, came
from the Greek word κόμη, which means "hair of the head". The Greek scientist and
philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw
as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with
three hairlike extensions.




                                     -
Comet
The word comet came to English by way of the Latin word cometes. This word, in turn, came
from the Greek word κόμη, which means "hair of the head". The Greek scientist and
philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw
as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with
three hairlike extensions.




                                     -
•   2006

•
• gmail
• twitter
• facebook updates
!

•               XHR

•      iframe

• FF   IE

•
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
HTML5 Standard
ws://example.com

wss://example.com
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com
                              New in draft#76
^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
my @keys = map {
    my $k = $env>{'HTTP_SEC_WEBSOCKET_KEY'.$_};
    join('', $k =~ m/d/g) / scalar @{[$k =~ m/ /g]};
} (1,2);

md5(pack('NN', @keys) . $key3);
Messages surrounded
by x{00} and x{ff}
Websockets API
Websockets API

ws = new WebSocket("ws://foo.com:5000”));

ws.onopen = function(ev) { ... }
ws.onmessage = function(ev) { ... }
ws.onclose = function(ev) { ... }
ws.onerror = function(ev) { ... }

ws.send(....);
Websockets API

    ws = new WebSocket("ws://foo.com:5000”));

    ws.onopen = function(ev) { ... }
    ws.onmessage = function(ev) { ... }
    ws.onclose = function(ev) { ... }
    ws.onerror = function(ev) { ... }

    ws.send(....);
Can accept cross-site connection with Origin and Sec-
             WebSocket-Origin headers
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
Web
•   : Websocket, MXHR
•                       : Websocket, MXHR

    enable "+Web::Hippie";
    sub { my $env    = shift;
          my $args   = $env->{'hippie.args'};
          my $handle = $env->{'hippie.handle'};

         # Your handler based on PATH_INFO:
         # /init, /error, /message
    }
•                       : Websocket, MXHR
                          Just a normal PSGI-app!
    enable "+Web::Hippie";
    sub { my $env    = shift;
          my $args   = $env->{'hippie.args'};
          my $handle = $env->{'hippie.handle'};

         # Your handler based on PATH_INFO:
         # /init, /error, /message
    }
•                       : Websocket, MXHR
                          mount it to /_hippie
    enable "+Web::Hippie";
    sub { my $env    = shift;
          my $args   = $env->{'hippie.args'};
          my $handle = $env->{'hippie.handle'};

         # Your handler based on PATH_INFO:
         # /init, /error, /message
    }
Must use PSGI servers supporting
    psgi.nonblocking:
Must use PSGI servers supporting
    psgi.nonblocking:


       twiggy
       feersum
Websocket
 mxhr     ?
?
…
Hippie::Pipe


     +
Hippie::Pipe
•                         :
    Websocket MXHR poll   AnyMQ support
Hippie::Pipe
•                          :
    Websocket MXHR poll   AnyMQ support
enable "+Web::Hippie";
enable "+Web::Hippie::Pipe", bus => AnyMQ->new;
sub { my $env    = shift;
      my $sub = $env->{'hippie.listener'};
      my $bus = $env->{'hippie.bus'};
      my $msg = $env->{'hippie.message'};
      # Your handler based on PATH_INFO:
      # /new_listener, /error, /message
}
Hippie::Pipe(Cont.)
Hippie::Pipe(Cont.)
my $topic = $bus->topic(‘news’);
# my $sub = $env->{'hippie.listener'};
if ($env->{PATH_INFO} eq ‘/new_listener’) {
   $sub->subscribe($topic);
}

# $topic->publish({type => ‘news.yapc’,
                   message => ‘something’});
Hippie::Pipe(Cont.)
my $topic = $bus->topic(‘news’);
# my $sub = $env->{'hippie.listener'};
if ($env->{PATH_INFO} eq ‘/new_listener’) {
   $sub->subscribe($topic);
}

# $topic->publish({type => ‘news.yapc’,
                   message => ‘something’});
Hippie::Pipe(Cont.)
my $topic = $bus->topic(‘news’);
# my $sub = $env->{'hippie.listener'};
if ($env->{PATH_INFO} eq ‘/new_listener’) {
   $sub->subscribe($topic);
}

# $topic->publish({type => ‘news.yapc’,
                   message => ‘something’});
hpipe = new Hippie.Pipe();
$(hpipe)
    .bind(“ready”, function() {
         hpipe.send({type:    ‘news.viewer’,
                     ident:   ‘clkao’})
     })
    .bind(“disconnected”, function() {})
    .bind(“message.news.yapc”,
           function(e, data) {});
hpipe.init();
hpipe = new Hippie.Pipe();
$(hpipe)
    .bind(“ready”, function() {
         hpipe.send({type:    ‘news.viewer’,
                     ident:   ‘clkao’})
     })
    .bind(“disconnected”, function() {})
    .bind(“message.news.yapc”,
           function(e, data) {});
hpipe.init();
hpipe = new Hippie.Pipe();
$(hpipe)
    .bind(“ready”, function() {
         hpipe.send
         hpipe.send({type:    ‘news.viewer’,
                     ident:   ‘clkao’})
     })
    .bind(“disconnected”, function() {})
    .bind(“message.news.yapc”,
           function(e, data) {});
hpipe.init();
hpipe = new Hippie.Pipe();
$(hpipe)
    .bind(“ready”, function() {
         hpipe.send
         hpipe.send({type:    ‘news.viewer’,
                     ident:   ‘clkao’})
     })
    .bind(“disconnected”, function() {})
    .bind(“message.news.yapc”,
           function(e, data) {});
hpipe.init();
Hippie::Pipe(Cont.)
Hippie::Pipe(Cont.)
# my $sub = $env->{'hippie.listener'};
# my $msg = $env->{'hippie.message'};

if ($env->{PATH_INFO} eq ‘/message’) {
   if ($msg->{type} eq ‘news.viewer’) {
     $topic->publish({type => ‘news.viewer’,
                      user => $msg->{user});
   }
}
Hippie::Pipe(Cont.)
# my $sub = $env->{'hippie.listener'};
# my $msg = $env->{'hippie.message'};

if ($env->{PATH_INFO} eq ‘/message’) {
   if ($msg->{type} eq ‘news.viewer’) {
     $topic->publish({type => ‘news.viewer’,
                      user => $msg->{user});
   }
}
Hippie::Pipe(Cont.)
# my $sub = $env->{'hippie.listener'};
# my $msg = $env->{'hippie.message'};

if ($env->{PATH_INFO} eq ‘/message’) {
   if ($msg->{type} eq ‘news.viewer’) {
     $topic->publish({type => ‘news.viewer’,
                      user => $msg->{user});
   }
}
# Client:
# bind(“message.news.viewer”, function(){..})
DEMO
at Jesse’s Talk 12:00
        today
DEMO
Thank you!
special thanks to Ishigaki-san and
   Danjou-san for translations

More Related Content

What's hot

Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and Lua
Jon Moore
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
Locaweb
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0
Tim Bunce
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
Hiroshi SHIBATA
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
Wim Godden
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxy
Ismael Celis
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Fernando Hamasaki de Amorim
 
DashProfiler 200807
DashProfiler 200807DashProfiler 200807
DashProfiler 200807
Tim Bunce
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
Laurent Dami
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
Wim Godden
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
Marcus Ramberg
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @SilexJeen Lee
 
Http capturing
Http capturingHttp capturing
Http capturing
Eric Ahn
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
charsbar
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
Kent Ohashi
 

What's hot (20)

Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and Lua
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
 
dotCloud and go
dotCloud and godotCloud and go
dotCloud and go
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxy
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
Gun make
Gun makeGun make
Gun make
 
DashProfiler 200807
DashProfiler 200807DashProfiler 200807
DashProfiler 200807
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
 
Http capturing
Http capturingHttp capturing
Http capturing
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 

Similar to AnyMQ, Hippie, and the real-time web

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
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門lestrrat
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
Olaf Alders
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Arc & Codementor
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたmemememomo
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
Jakub Zalas
 
ZeroMQ Is The Answer: PHP Tek 11 Version
ZeroMQ Is The Answer: PHP Tek 11 VersionZeroMQ Is The Answer: PHP Tek 11 Version
ZeroMQ Is The Answer: PHP Tek 11 Version
Ian Barber
 
ZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 Version
Ian Barber
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
Ben Scofield
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The Answer
Ian Barber
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoMasahiro Nagano
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked aboutTatsuhiko Miyagawa
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
Masahiro Nagano
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
Amazon Web Services
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
Dave Cross
 

Similar to AnyMQ, Hippie, and the real-time web (20)

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
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみた
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
ZeroMQ Is The Answer: PHP Tek 11 Version
ZeroMQ Is The Answer: PHP Tek 11 VersionZeroMQ Is The Answer: PHP Tek 11 Version
ZeroMQ Is The Answer: PHP Tek 11 Version
 
ZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 Version
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The Answer
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 

More from clkao

Open Source, Open Data, Open Government
Open Source, Open Data, Open GovernmentOpen Source, Open Data, Open Government
Open Source, Open Data, Open Government
clkao
 
Websockets at tossug
Websockets at tossugWebsockets at tossug
Websockets at tossugclkao
 
"Lego Programming" with Lorzy
"Lego Programming" with Lorzy"Lego Programming" with Lorzy
"Lego Programming" with Lorzyclkao
 
Devel::NYTProf
Devel::NYTProfDevel::NYTProf
Devel::NYTProfclkao
 
Trading With Open Source Tools
Trading With Open Source ToolsTrading With Open Source Tools
Trading With Open Source Tools
clkao
 
Twopenhack08 Fnord
Twopenhack08 FnordTwopenhack08 Fnord
Twopenhack08 Fnordclkao
 
Svk Br Yapceu2008
Svk Br Yapceu2008Svk Br Yapceu2008
Svk Br Yapceu2008clkao
 
prototype::signatures
prototype::signaturesprototype::signatures
prototype::signatures
clkao
 
Leon & Andrea
Leon & AndreaLeon & Andrea
Leon & Andreaclkao
 

More from clkao (9)

Open Source, Open Data, Open Government
Open Source, Open Data, Open GovernmentOpen Source, Open Data, Open Government
Open Source, Open Data, Open Government
 
Websockets at tossug
Websockets at tossugWebsockets at tossug
Websockets at tossug
 
"Lego Programming" with Lorzy
"Lego Programming" with Lorzy"Lego Programming" with Lorzy
"Lego Programming" with Lorzy
 
Devel::NYTProf
Devel::NYTProfDevel::NYTProf
Devel::NYTProf
 
Trading With Open Source Tools
Trading With Open Source ToolsTrading With Open Source Tools
Trading With Open Source Tools
 
Twopenhack08 Fnord
Twopenhack08 FnordTwopenhack08 Fnord
Twopenhack08 Fnord
 
Svk Br Yapceu2008
Svk Br Yapceu2008Svk Br Yapceu2008
Svk Br Yapceu2008
 
prototype::signatures
prototype::signaturesprototype::signatures
prototype::signatures
 
Leon & Andrea
Leon & AndreaLeon & Andrea
Leon & Andrea
 

Recently uploaded

Digital Transformation and IT Strategy Toolkit and Templates
Digital Transformation and IT Strategy Toolkit and TemplatesDigital Transformation and IT Strategy Toolkit and Templates
Digital Transformation and IT Strategy Toolkit and Templates
Aurelien Domont, MBA
 
3.0 Project 2_ Developing My Brand Identity Kit.pptx
3.0 Project 2_ Developing My Brand Identity Kit.pptx3.0 Project 2_ Developing My Brand Identity Kit.pptx
3.0 Project 2_ Developing My Brand Identity Kit.pptx
tanyjahb
 
Affordable Stationery Printing Services in Jaipur | Navpack n Print
Affordable Stationery Printing Services in Jaipur | Navpack n PrintAffordable Stationery Printing Services in Jaipur | Navpack n Print
Affordable Stationery Printing Services in Jaipur | Navpack n Print
Navpack & Print
 
anas about venice for grade 6f about venice
anas about venice for grade 6f about veniceanas about venice for grade 6f about venice
anas about venice for grade 6f about venice
anasabutalha2013
 
Brand Analysis for an artist named Struan
Brand Analysis for an artist named StruanBrand Analysis for an artist named Struan
Brand Analysis for an artist named Struan
sarahvanessa51503
 
Premium MEAN Stack Development Solutions for Modern Businesses
Premium MEAN Stack Development Solutions for Modern BusinessesPremium MEAN Stack Development Solutions for Modern Businesses
Premium MEAN Stack Development Solutions for Modern Businesses
SynapseIndia
 
What are the main advantages of using HR recruiter services.pdf
What are the main advantages of using HR recruiter services.pdfWhat are the main advantages of using HR recruiter services.pdf
What are the main advantages of using HR recruiter services.pdf
HumanResourceDimensi1
 
Kseniya Leshchenko: Shared development support service model as the way to ma...
Kseniya Leshchenko: Shared development support service model as the way to ma...Kseniya Leshchenko: Shared development support service model as the way to ma...
Kseniya Leshchenko: Shared development support service model as the way to ma...
Lviv Startup Club
 
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
taqyed
 
VAT Registration Outlined In UAE: Benefits and Requirements
VAT Registration Outlined In UAE: Benefits and RequirementsVAT Registration Outlined In UAE: Benefits and Requirements
VAT Registration Outlined In UAE: Benefits and Requirements
uae taxgpt
 
Skye Residences | Extended Stay Residences Near Toronto Airport
Skye Residences | Extended Stay Residences Near Toronto AirportSkye Residences | Extended Stay Residences Near Toronto Airport
Skye Residences | Extended Stay Residences Near Toronto Airport
marketingjdass
 
Attending a job Interview for B1 and B2 Englsih learners
Attending a job Interview for B1 and B2 Englsih learnersAttending a job Interview for B1 and B2 Englsih learners
Attending a job Interview for B1 and B2 Englsih learners
Erika906060
 
Business Valuation Principles for Entrepreneurs
Business Valuation Principles for EntrepreneursBusiness Valuation Principles for Entrepreneurs
Business Valuation Principles for Entrepreneurs
Ben Wann
 
Buy Verified PayPal Account | Buy Google 5 Star Reviews
Buy Verified PayPal Account | Buy Google 5 Star ReviewsBuy Verified PayPal Account | Buy Google 5 Star Reviews
Buy Verified PayPal Account | Buy Google 5 Star Reviews
usawebmarket
 
Project File Report BBA 6th semester.pdf
Project File Report BBA 6th semester.pdfProject File Report BBA 6th semester.pdf
Project File Report BBA 6th semester.pdf
RajPriye
 
Exploring Patterns of Connection with Social Dreaming
Exploring Patterns of Connection with Social DreamingExploring Patterns of Connection with Social Dreaming
Exploring Patterns of Connection with Social Dreaming
Nicola Wreford-Howard
 
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
BBPMedia1
 
Discover the innovative and creative projects that highlight my journey throu...
Discover the innovative and creative projects that highlight my journey throu...Discover the innovative and creative projects that highlight my journey throu...
Discover the innovative and creative projects that highlight my journey throu...
dylandmeas
 
FINAL PRESENTATION.pptx12143241324134134
FINAL PRESENTATION.pptx12143241324134134FINAL PRESENTATION.pptx12143241324134134
FINAL PRESENTATION.pptx12143241324134134
LR1709MUSIC
 
Enterprise Excellence is Inclusive Excellence.pdf
Enterprise Excellence is Inclusive Excellence.pdfEnterprise Excellence is Inclusive Excellence.pdf
Enterprise Excellence is Inclusive Excellence.pdf
KaiNexus
 

Recently uploaded (20)

Digital Transformation and IT Strategy Toolkit and Templates
Digital Transformation and IT Strategy Toolkit and TemplatesDigital Transformation and IT Strategy Toolkit and Templates
Digital Transformation and IT Strategy Toolkit and Templates
 
3.0 Project 2_ Developing My Brand Identity Kit.pptx
3.0 Project 2_ Developing My Brand Identity Kit.pptx3.0 Project 2_ Developing My Brand Identity Kit.pptx
3.0 Project 2_ Developing My Brand Identity Kit.pptx
 
Affordable Stationery Printing Services in Jaipur | Navpack n Print
Affordable Stationery Printing Services in Jaipur | Navpack n PrintAffordable Stationery Printing Services in Jaipur | Navpack n Print
Affordable Stationery Printing Services in Jaipur | Navpack n Print
 
anas about venice for grade 6f about venice
anas about venice for grade 6f about veniceanas about venice for grade 6f about venice
anas about venice for grade 6f about venice
 
Brand Analysis for an artist named Struan
Brand Analysis for an artist named StruanBrand Analysis for an artist named Struan
Brand Analysis for an artist named Struan
 
Premium MEAN Stack Development Solutions for Modern Businesses
Premium MEAN Stack Development Solutions for Modern BusinessesPremium MEAN Stack Development Solutions for Modern Businesses
Premium MEAN Stack Development Solutions for Modern Businesses
 
What are the main advantages of using HR recruiter services.pdf
What are the main advantages of using HR recruiter services.pdfWhat are the main advantages of using HR recruiter services.pdf
What are the main advantages of using HR recruiter services.pdf
 
Kseniya Leshchenko: Shared development support service model as the way to ma...
Kseniya Leshchenko: Shared development support service model as the way to ma...Kseniya Leshchenko: Shared development support service model as the way to ma...
Kseniya Leshchenko: Shared development support service model as the way to ma...
 
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
一比一原版加拿大渥太华大学毕业证(uottawa毕业证书)如何办理
 
VAT Registration Outlined In UAE: Benefits and Requirements
VAT Registration Outlined In UAE: Benefits and RequirementsVAT Registration Outlined In UAE: Benefits and Requirements
VAT Registration Outlined In UAE: Benefits and Requirements
 
Skye Residences | Extended Stay Residences Near Toronto Airport
Skye Residences | Extended Stay Residences Near Toronto AirportSkye Residences | Extended Stay Residences Near Toronto Airport
Skye Residences | Extended Stay Residences Near Toronto Airport
 
Attending a job Interview for B1 and B2 Englsih learners
Attending a job Interview for B1 and B2 Englsih learnersAttending a job Interview for B1 and B2 Englsih learners
Attending a job Interview for B1 and B2 Englsih learners
 
Business Valuation Principles for Entrepreneurs
Business Valuation Principles for EntrepreneursBusiness Valuation Principles for Entrepreneurs
Business Valuation Principles for Entrepreneurs
 
Buy Verified PayPal Account | Buy Google 5 Star Reviews
Buy Verified PayPal Account | Buy Google 5 Star ReviewsBuy Verified PayPal Account | Buy Google 5 Star Reviews
Buy Verified PayPal Account | Buy Google 5 Star Reviews
 
Project File Report BBA 6th semester.pdf
Project File Report BBA 6th semester.pdfProject File Report BBA 6th semester.pdf
Project File Report BBA 6th semester.pdf
 
Exploring Patterns of Connection with Social Dreaming
Exploring Patterns of Connection with Social DreamingExploring Patterns of Connection with Social Dreaming
Exploring Patterns of Connection with Social Dreaming
 
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
RMD24 | Debunking the non-endemic revenue myth Marvin Vacquier Droop | First ...
 
Discover the innovative and creative projects that highlight my journey throu...
Discover the innovative and creative projects that highlight my journey throu...Discover the innovative and creative projects that highlight my journey throu...
Discover the innovative and creative projects that highlight my journey throu...
 
FINAL PRESENTATION.pptx12143241324134134
FINAL PRESENTATION.pptx12143241324134134FINAL PRESENTATION.pptx12143241324134134
FINAL PRESENTATION.pptx12143241324134134
 
Enterprise Excellence is Inclusive Excellence.pdf
Enterprise Excellence is Inclusive Excellence.pdfEnterprise Excellence is Inclusive Excellence.pdf
Enterprise Excellence is Inclusive Excellence.pdf
 

AnyMQ, Hippie, and the real-time web

  • 1. AnyMQ, Hippie and the real-time web YAPC::Asia 2010 Tokyo Chia-liang Kao clkao@clkao.org
  • 2.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie:Pipe
  • 11. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 13. PSGI
  • 14. $env [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]
  • 15. $env->{PATH_INFO} $env [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]
  • 16. $env->{PATH_INFO} Plack::Request->new($env)->path_info $env [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]
  • 17. $env Streaming Interface sub { my $responder = shift; my $writer = $responder->([ '200', [ 'Content-Type' => 'text/plain' ]); # later, of in a callback $writer->write(“Hello world!”); $writer->close(); }
  • 18. $env Streaming Interface(Cont.) sub { my $responder = shift; my $writer = $responder->([ '200', [ 'Content-Type' => 'text/plain' ]); # later, of in a callback my $w; $w = AnyEvent->timer(after => 3, cb => sub { $writer->write(“Hello world!”); $writer->close(); }); }
  • 20. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 22. AnyEvent • • use AnyEvent::HTTP; http_get "http://yapc.asia/", sub { print $_[1] }; # do something else
  • 23. POE
  • 24. sub POE::Kernel::ASSERT_DEFAULT () { 1 } use HTTP::Request; use POE qw(Component::Client::HTTP); POE::Component::Client::HTTP->spawn(   Alias => 'ua', # defaults to 'weeble'   Timeout => 20, # defaults to 180 seconds ); POE::Session->create(   inline_states => {     _start => sub {       POE::Kernel->post(         'ua', # posts to the 'ua' alias         'request', # posts to ua's 'request' state         'response', # which of our states will receive the response         HTTP::Request->new(GET => “http://osdc.tw”),       );     },     _stop => sub {},     response => &response_handler,   }, ); POE::Kernel->run(); exit; sub response_handler {   my ($request_packet, $response_packet) = @_[ARG0, ARG1];   my $request_object = $request_packet->[0];   my $response_object = $response_packet->[0]; }
  • 25.
  • 27. AnyEvent::* AnyEvent-AIO AnyEvent-APNS AnyEvent-Atom-Stream AnyEvent-BDB AnyEvent- Beanstalk AnyEvent-Connection AnyEvent-CouchDB AnyEvent-DBI AnyEvent-DBI- Abstract AnyEvent-EditText AnyEvent-FCGI AnyEvent-FCP AnyEvent-FIFO AnyEvent- FastPing AnyEvent-Feed AnyEvent-Filesys-Notify AnyEvent-FriendFeed-Realtime AnyEvent-GPSD AnyEvent-Gearman AnyEvent-Gearman AnyEvent-Gmail-Feed AnyEvent-HTTP AnyEvent-HTTP-MXHR AnyEvent-HTTPD AnyEvent-I3 AnyEvent-IRC AnyEvent-JSONRPC-Lite AnyEvent-Kanye AnyEvent-MP AnyEvent-MPRPC AnyEvent- Memcached AnyEvent-Mojo AnyEvent-Monitor-CPU AnyEvent-Pcap AnyEvent-Plurk AnyEvent-Postfix-Logs AnyEvent-RTPG AnyEvent-Redis AnyEvent-RetryTimer AnyEvent-ReverseHTTP AnyEvent-Riak AnyEvent-Run AnyEvent-SCGI AnyEvent-SMTP AnyEvent-SNMP AnyEvent-Subprocess AnyEvent-Superfeedr AnyEvent-Twitter AnyEvent-Twitter-Stream AnyEvent-Watchdog AnyEvent-Worker AnyEvent-XMLRPC AnyEvent-XMPP AnyEvent-mDNS
  • 28. AnyMQ
  • 36. AnyMQ my $bus = AnyMQ->new; my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $topic->publish($msg)
  • 37. AnyMQ with AMQP my $bus = AnyMQ->new_with_traits ( traits => [ ‘AMQP’], # host => ..., port => ..); my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $topic->publish($msg)
  • 39. AnyMQ with AMQP my $bus = AnyMQ->new_with_traits my $bus = AnyMQ->new_with_traits ( traits => [ ‘AMQP’], ( traits => [ ‘AMQP’], # host => ..., port => ..); # host => ..., port => ..); my $topic = $bus->topic("Foo"); my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $sub->poll(sub { my $msg = shift; }) $topic->publish($msg) $topic->publish($msg) my $bus = AnyMQ->new_with_traits my $bus = AnyMQ->new_with_traits ( traits => [ ‘AMQP’], ( traits => [ ‘AMQP’], # host => ..., port => ..); # host => ..., port => ..); my $topic = $bus->topic("Foo"); my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $sub->poll(sub { my $msg = shift; }) $topic->publish($msg) $topic->publish($msg)
  • 40. AnyMQ with AMQP my $bus = AnyMQ->new_with_traits my $bus = AnyMQ->new_with_traits ( traits => [ ‘AMQP’], ( traits => [ ‘AMQP’], # host => ..., port => ..); # host => ..., port => ..); my $topic = $bus->topic("Foo"); my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $sub->poll(sub { my $msg = shift; }) $topic->publish($msg) $topic->publish($msg) AMQP Server my $bus = AnyMQ->new_with_traits my $bus = AnyMQ->new_with_traits ( traits => [ ‘AMQP’], ( traits => [ ‘AMQP’], # host => ..., port => ..); # host => ..., port => ..); my $topic = $bus->topic("Foo"); my $topic = $bus->topic("Foo"); my $sub = $bus->new_listener($topic); my $sub = $bus->new_listener($topic); $sub->poll(sub { my $msg = shift; }) $sub->poll(sub { my $msg = shift; }) $topic->publish($msg) $topic->publish($msg)
  • 41. !
  • 42. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 44. Comet The word comet came to English by way of the Latin word cometes. This word, in turn, came from the Greek word κόμη, which means "hair of the head". The Greek scientist and philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with three hairlike extensions. -
  • 45. Comet The word comet came to English by way of the Latin word cometes. This word, in turn, came from the Greek word κόμη, which means "hair of the head". The Greek scientist and philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with three hairlike extensions. - • 2006 •
  • 46. • gmail • twitter • facebook updates
  • 47. ! • XHR • iframe • FF IE •
  • 48. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 49.
  • 52. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 53. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 54. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 55. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 56. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 57. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 58. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 59. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 60. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com New in draft#76 ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 61. my @keys = map { my $k = $env>{'HTTP_SEC_WEBSOCKET_KEY'.$_}; join('', $k =~ m/d/g) / scalar @{[$k =~ m/ /g]}; } (1,2); md5(pack('NN', @keys) . $key3);
  • 64. Websockets API ws = new WebSocket("ws://foo.com:5000”)); ws.onopen = function(ev) { ... } ws.onmessage = function(ev) { ... } ws.onclose = function(ev) { ... } ws.onerror = function(ev) { ... } ws.send(....);
  • 65. Websockets API ws = new WebSocket("ws://foo.com:5000”)); ws.onopen = function(ev) { ... } ws.onmessage = function(ev) { ... } ws.onclose = function(ev) { ... } ws.onerror = function(ev) { ... } ws.send(....); Can accept cross-site connection with Origin and Sec- WebSocket-Origin headers
  • 66. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 67. Request: GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 68.
  • 69. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 70. Web
  • 71.
  • 72. : Websocket, MXHR
  • 73. : Websocket, MXHR enable "+Web::Hippie"; sub { my $env = shift; my $args = $env->{'hippie.args'}; my $handle = $env->{'hippie.handle'}; # Your handler based on PATH_INFO: # /init, /error, /message }
  • 74. : Websocket, MXHR Just a normal PSGI-app! enable "+Web::Hippie"; sub { my $env = shift; my $args = $env->{'hippie.args'}; my $handle = $env->{'hippie.handle'}; # Your handler based on PATH_INFO: # /init, /error, /message }
  • 75. : Websocket, MXHR mount it to /_hippie enable "+Web::Hippie"; sub { my $env = shift; my $args = $env->{'hippie.args'}; my $handle = $env->{'hippie.handle'}; # Your handler based on PATH_INFO: # /init, /error, /message }
  • 76. Must use PSGI servers supporting psgi.nonblocking:
  • 77. Must use PSGI servers supporting psgi.nonblocking: twiggy feersum
  • 79. ?
  • 80.
  • 82. Hippie::Pipe • : Websocket MXHR poll AnyMQ support
  • 83. Hippie::Pipe • : Websocket MXHR poll AnyMQ support enable "+Web::Hippie"; enable "+Web::Hippie::Pipe", bus => AnyMQ->new; sub { my $env = shift; my $sub = $env->{'hippie.listener'}; my $bus = $env->{'hippie.bus'}; my $msg = $env->{'hippie.message'}; # Your handler based on PATH_INFO: # /new_listener, /error, /message }
  • 85. Hippie::Pipe(Cont.) my $topic = $bus->topic(‘news’); # my $sub = $env->{'hippie.listener'}; if ($env->{PATH_INFO} eq ‘/new_listener’) { $sub->subscribe($topic); } # $topic->publish({type => ‘news.yapc’, message => ‘something’});
  • 86. Hippie::Pipe(Cont.) my $topic = $bus->topic(‘news’); # my $sub = $env->{'hippie.listener'}; if ($env->{PATH_INFO} eq ‘/new_listener’) { $sub->subscribe($topic); } # $topic->publish({type => ‘news.yapc’, message => ‘something’});
  • 87. Hippie::Pipe(Cont.) my $topic = $bus->topic(‘news’); # my $sub = $env->{'hippie.listener'}; if ($env->{PATH_INFO} eq ‘/new_listener’) { $sub->subscribe($topic); } # $topic->publish({type => ‘news.yapc’, message => ‘something’});
  • 88. hpipe = new Hippie.Pipe(); $(hpipe) .bind(“ready”, function() { hpipe.send({type: ‘news.viewer’, ident: ‘clkao’}) }) .bind(“disconnected”, function() {}) .bind(“message.news.yapc”, function(e, data) {}); hpipe.init();
  • 89. hpipe = new Hippie.Pipe(); $(hpipe) .bind(“ready”, function() { hpipe.send({type: ‘news.viewer’, ident: ‘clkao’}) }) .bind(“disconnected”, function() {}) .bind(“message.news.yapc”, function(e, data) {}); hpipe.init();
  • 90. hpipe = new Hippie.Pipe(); $(hpipe) .bind(“ready”, function() { hpipe.send hpipe.send({type: ‘news.viewer’, ident: ‘clkao’}) }) .bind(“disconnected”, function() {}) .bind(“message.news.yapc”, function(e, data) {}); hpipe.init();
  • 91. hpipe = new Hippie.Pipe(); $(hpipe) .bind(“ready”, function() { hpipe.send hpipe.send({type: ‘news.viewer’, ident: ‘clkao’}) }) .bind(“disconnected”, function() {}) .bind(“message.news.yapc”, function(e, data) {}); hpipe.init();
  • 93. Hippie::Pipe(Cont.) # my $sub = $env->{'hippie.listener'}; # my $msg = $env->{'hippie.message'}; if ($env->{PATH_INFO} eq ‘/message’) { if ($msg->{type} eq ‘news.viewer’) { $topic->publish({type => ‘news.viewer’, user => $msg->{user}); } }
  • 94. Hippie::Pipe(Cont.) # my $sub = $env->{'hippie.listener'}; # my $msg = $env->{'hippie.message'}; if ($env->{PATH_INFO} eq ‘/message’) { if ($msg->{type} eq ‘news.viewer’) { $topic->publish({type => ‘news.viewer’, user => $msg->{user}); } }
  • 95. Hippie::Pipe(Cont.) # my $sub = $env->{'hippie.listener'}; # my $msg = $env->{'hippie.message'}; if ($env->{PATH_INFO} eq ‘/message’) { if ($msg->{type} eq ‘news.viewer’) { $topic->publish({type => ‘news.viewer’, user => $msg->{user}); } } # Client: # bind(“message.news.viewer”, function(){..})
  • 96. DEMO at Jesse’s Talk 12:00 today
  • 97. DEMO
  • 98. Thank you! special thanks to Ishigaki-san and Danjou-san for translations

Editor's Notes

  1. most of the time i am cooking
  2. sometimes i wrote some code
  3. things i ve been playing with
  4. multiple event loop
  5. time out handler supported
  6. time out handler supported
  7. time out handler supported
  8. time out handler supported
  9. time out handler supported
  10. time out handler supported
  11. time out handler supported
  12. time out handler supported
  13. please help writing mq bindings
  14. 2006, coined by Alex Russell Server push for real time notification
  15. 2006, coined by Alex Russell Server push for real time notification
  16. multi-part XHR forever iframe, with script callbacks spinning “loading” indicator for FF and IE number of connections limits
  17. only websockets and mxhr?
  18. maybe hippies should be more relaxed