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

       YAPC::Asia 2010 Tokyo
   Chia-liang Kao clkao@clkao.org
AnyMQ, Hippie, and the real-time web
clkao
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
• 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
AnyMQ, Hippie, and the real-time web
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-
AnyMQ, Hippie, and the real-time web
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
Web
AnyMQ, Hippie, and the real-time 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

PDF
Trading with opensource tools, two years later
clkao
 
PDF
RestMQ - HTTP/Redis based Message Queue
Gleicon Moraes
 
PDF
Using ngx_lua in UPYUN
Cong Zhang
 
PDF
Follow the White Rabbit - Message Queues with PHP
Eric Rodriguez (Hiring in Lex)
 
PDF
Redis & ZeroMQ: How to scale your application
rjsmelo
 
PPTX
Webrtc mojo
bpmedley
 
PDF
Redis as a message queue
Brandon Lamb
 
ODP
PHP5.5 is Here
julien pauli
 
Trading with opensource tools, two years later
clkao
 
RestMQ - HTTP/Redis based Message Queue
Gleicon Moraes
 
Using ngx_lua in UPYUN
Cong Zhang
 
Follow the White Rabbit - Message Queues with PHP
Eric Rodriguez (Hiring in Lex)
 
Redis & ZeroMQ: How to scale your application
rjsmelo
 
Webrtc mojo
bpmedley
 
Redis as a message queue
Brandon Lamb
 
PHP5.5 is Here
julien pauli
 

What's hot (20)

PDF
Roll Your Own API Management Platform with nginx and Lua
Jon Moore
 
PDF
Lua tech talk
Locaweb
 
KEY
dotCloud and go
Flavio Poletti
 
PDF
PL/Perl - New Features in PostgreSQL 9.0
Tim Bunce
 
PDF
High Performance tDiary
Hiroshi SHIBATA
 
PDF
Perl web frameworks
diego_k
 
ODP
The promise of asynchronous php
Wim Godden
 
PDF
Node.js streaming csv downloads proxy
Ismael Celis
 
PDF
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Fernando Hamasaki de Amorim
 
PPTX
Gun make
psychesnet Hsieh
 
KEY
DashProfiler 200807
Tim Bunce
 
PPTX
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
ZIP
Web Apps in Perl - HTTP 101
hendrikvb
 
PPT
Working with databases in Perl
Laurent Dami
 
ODP
Caching and tuning fun for high scalability
Wim Godden
 
KEY
Mojo as a_client
Marcus Ramberg
 
PDF
Smolder @Silex
Jeen Lee
 
PDF
Http capturing
Eric Ahn
 
PPT
On UnQLite
charsbar
 
PDF
Interceptors: Into the Core of Pedestal
Kent Ohashi
 
Roll Your Own API Management Platform with nginx and Lua
Jon Moore
 
Lua tech talk
Locaweb
 
dotCloud and go
Flavio Poletti
 
PL/Perl - New Features in PostgreSQL 9.0
Tim Bunce
 
High Performance tDiary
Hiroshi SHIBATA
 
Perl web frameworks
diego_k
 
The promise of asynchronous php
Wim Godden
 
Node.js streaming csv downloads proxy
Ismael Celis
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Fernando Hamasaki de Amorim
 
DashProfiler 200807
Tim Bunce
 
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
Web Apps in Perl - HTTP 101
hendrikvb
 
Working with databases in Perl
Laurent Dami
 
Caching and tuning fun for high scalability
Wim Godden
 
Mojo as a_client
Marcus Ramberg
 
Smolder @Silex
Jeen Lee
 
Http capturing
Eric Ahn
 
On UnQLite
charsbar
 
Interceptors: Into the Core of Pedestal
Kent Ohashi
 
Ad

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

PDF
AnyMQ, Hippie, and the real-time web
clkao
 
KEY
Tatsumaki
Tatsuhiko Miyagawa
 
PDF
RabbitMQ for Perl mongers
Lenz Gschwendtner
 
ZIP
Websockets at tossug
clkao
 
KEY
Messaging, interoperability and log aggregation - a new framework
Tomas Doran
 
PDF
IoTaConf 2014 - IoT Connectivity, Standards, and Architecture
Todd Montgomery
 
KEY
Plack perl superglue for web frameworks and servers
Tatsuhiko Miyagawa
 
PDF
How to build a scalable SNS via Polling & Push
Mu Chun Wang
 
PDF
NullMQ @ PDX
Jeff Lindsay
 
KEY
ZeroMQ
Stoyan Zhekov
 
KEY
Plack at YAPC::NA 2010
Tatsuhiko Miyagawa
 
PDF
ZeroMQ Is The Answer: DPC 11 Version
Ian Barber
 
PDF
IoT - Understanding internet of things
veerababu penugonda(Mr-IoT)
 
PPTX
Ws
Sunghan Kim
 
PPT
Rabbit MQ introduction
Sitg Yao
 
KEY
Intro to PSGI and Plack
Tatsuhiko Miyagawa
 
KEY
Message Queueing - by an MQ noob
Richard Jones
 
PDF
ZeroMQ Is The Answer: PHP Tek 11 Version
Ian Barber
 
KEY
Message queueing
Richard Jones
 
AnyMQ, Hippie, and the real-time web
clkao
 
RabbitMQ for Perl mongers
Lenz Gschwendtner
 
Websockets at tossug
clkao
 
Messaging, interoperability and log aggregation - a new framework
Tomas Doran
 
IoTaConf 2014 - IoT Connectivity, Standards, and Architecture
Todd Montgomery
 
Plack perl superglue for web frameworks and servers
Tatsuhiko Miyagawa
 
How to build a scalable SNS via Polling & Push
Mu Chun Wang
 
NullMQ @ PDX
Jeff Lindsay
 
Plack at YAPC::NA 2010
Tatsuhiko Miyagawa
 
ZeroMQ Is The Answer: DPC 11 Version
Ian Barber
 
IoT - Understanding internet of things
veerababu penugonda(Mr-IoT)
 
Rabbit MQ introduction
Sitg Yao
 
Intro to PSGI and Plack
Tatsuhiko Miyagawa
 
Message Queueing - by an MQ noob
Richard Jones
 
ZeroMQ Is The Answer: PHP Tek 11 Version
Ian Barber
 
Message queueing
Richard Jones
 
Ad

More from clkao (8)

PDF
Open Source, Open Data, Open Government
clkao
 
PDF
"Lego Programming" with Lorzy
clkao
 
PDF
Devel::NYTProf
clkao
 
PDF
Trading With Open Source Tools
clkao
 
PDF
Twopenhack08 Fnord
clkao
 
PDF
Svk Br Yapceu2008
clkao
 
PDF
prototype::signatures
clkao
 
PDF
Leon & Andrea
clkao
 
Open Source, Open Data, Open Government
clkao
 
"Lego Programming" with Lorzy
clkao
 
Devel::NYTProf
clkao
 
Trading With Open Source Tools
clkao
 
Twopenhack08 Fnord
clkao
 
Svk Br Yapceu2008
clkao
 
prototype::signatures
clkao
 
Leon & Andrea
clkao
 

Recently uploaded (20)

PDF
GenAI for Risk Management: Refresher for the Boards and Executives
Alexei Sidorenko, CRMP
 
PPTX
Virbyze_Our company profile_Preview.pptx
myckwabs
 
PPTX
Memorandum and articles of association explained.pptx
Keerthana Chinnathambi
 
PDF
Followers to Fees - Social media for Speakers
Corey Perlman, Social Media Speaker and Consultant
 
PPTX
Chapter 3 Distributive Negotiation: Claiming Value
badranomar1990
 
PDF
2025 07 29 The Future, Backwards Agile 2025.pdf
Daniel Walsh
 
PPTX
Appreciations - July 25.pptxdddddddddddss
anushavnayak
 
PDF
askOdin - An Introduction to AI-Powered Investment Judgment
YekSoon LOK
 
PDF
Using Innovative Solar Manufacturing to Drive India's Renewable Energy Revolu...
Insolation Energy
 
PDF
MBA-I-Year-Session-2024-20hzuxutiytidydy
cminati49
 
PDF
NewBase 24 July 2025 Energy News issue - 1805 by Khaled Al Awadi._compressed...
Khaled Al Awadi
 
PDF
Retinal Disorder Treatment Market 2030: The Impact of Advanced Diagnostics an...
Kumar Satyam
 
PPTX
Business Plan Presentation: Vision, Strategy, Services, Growth Goals & Future...
neelsoni2108
 
PPTX
Final PPT on DAJGUA, EV Charging, Meter Devoloution, CGRF, Annual Accounts & ...
directord
 
PDF
Unveiling the Latest Threat Intelligence Practical Strategies for Strengtheni...
Auxis Consulting & Outsourcing
 
PDF
Gregory Felber - An Accomplished Underwater Marine Biologist
Gregory Felber
 
PPTX
Social Media Marketing for Business Growth
vidhi622006
 
PDF
New Royals Distribution Plan Presentation
ksherwin
 
PDF
Tariff Surcharge and Price Increase Decision
Joshua Gao
 
PPTX
Appreciations - July 25.pptxffsdjjjjjjjjjjjj
anushavnayak
 
GenAI for Risk Management: Refresher for the Boards and Executives
Alexei Sidorenko, CRMP
 
Virbyze_Our company profile_Preview.pptx
myckwabs
 
Memorandum and articles of association explained.pptx
Keerthana Chinnathambi
 
Followers to Fees - Social media for Speakers
Corey Perlman, Social Media Speaker and Consultant
 
Chapter 3 Distributive Negotiation: Claiming Value
badranomar1990
 
2025 07 29 The Future, Backwards Agile 2025.pdf
Daniel Walsh
 
Appreciations - July 25.pptxdddddddddddss
anushavnayak
 
askOdin - An Introduction to AI-Powered Investment Judgment
YekSoon LOK
 
Using Innovative Solar Manufacturing to Drive India's Renewable Energy Revolu...
Insolation Energy
 
MBA-I-Year-Session-2024-20hzuxutiytidydy
cminati49
 
NewBase 24 July 2025 Energy News issue - 1805 by Khaled Al Awadi._compressed...
Khaled Al Awadi
 
Retinal Disorder Treatment Market 2030: The Impact of Advanced Diagnostics an...
Kumar Satyam
 
Business Plan Presentation: Vision, Strategy, Services, Growth Goals & Future...
neelsoni2108
 
Final PPT on DAJGUA, EV Charging, Meter Devoloution, CGRF, Annual Accounts & ...
directord
 
Unveiling the Latest Threat Intelligence Practical Strategies for Strengtheni...
Auxis Consulting & Outsourcing
 
Gregory Felber - An Accomplished Underwater Marine Biologist
Gregory Felber
 
Social Media Marketing for Business Growth
vidhi622006
 
New Royals Distribution Plan Presentation
ksherwin
 
Tariff Surcharge and Price Increase Decision
Joshua Gao
 
Appreciations - July 25.pptxffsdjjjjjjjjjjjj
anushavnayak
 

AnyMQ, Hippie, and the real-time web

  • 1. AnyMQ, Hippie and the real-time web YAPC::Asia 2010 Tokyo Chia-liang Kao [email protected]
  • 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
  • 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-
  • 69. • PSGI, Plack • AnyEvent, AnyMQ, AMQP • Server-push, comet • Websocket • Web::Hippie, Web::Hippie::Pipe
  • 70. Web
  • 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

  • #5: most of the time i am cooking
  • #8: sometimes i wrote some code
  • #9: things i ve been playing with
  • #24: multiple event loop
  • #30: time out handler supported
  • #31: time out handler supported
  • #32: time out handler supported
  • #33: time out handler supported
  • #34: time out handler supported
  • #35: time out handler supported
  • #36: time out handler supported
  • #37: time out handler supported
  • #45: please help writing mq bindings
  • #47: 2006, coined by Alex Russell Server push for real time notification
  • #48: 2006, coined by Alex Russell Server push for real time notification
  • #50: multi-part XHR forever iframe, with script callbacks spinning “loading” indicator for FF and IE number of connections limits
  • #79: only websockets and mxhr?
  • #80: maybe hippies should be more relaxed