AnyMQ, Hippie, and the real-time web
Transcript of AnyMQ, Hippie, and the real-time web
![Page 2: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/2.jpg)
高嘉良
![Page 3: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/3.jpg)
clkao
![Page 4: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/4.jpg)
Things I’ve been playing
with
![Page 5: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/5.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie:Pipe
![Page 6: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/6.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
![Page 7: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/7.jpg)
Plack: Perl Web Superglue
![Page 8: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/8.jpg)
PSGI
![Page 9: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/9.jpg)
$env
[ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]
$env->{PATH_INFO}
Plack::Request->new($env)->path_info
![Page 10: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/10.jpg)
$env
sub { my $responder = shift;
my $writer = $responder->([ '200', [ 'Content-Type' => 'text/plain' ]); # later, of in a callback $writer->write(“Hello world!”); $writer->close();}
Streaming Interface
![Page 11: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/11.jpg)
CGI.pmMUST DIE! ☠! ☠! ☠
![Page 12: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/12.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
![Page 13: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/13.jpg)
AnyEvent
• event-driven programming, painless
• compatible with many other event loops
use AnyEvent::HTTP;
http_get "http://osdc.tw/", sub { print $_[1] };
![Page 14: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/14.jpg)
Let’s try this in POE
![Page 15: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/15.jpg)
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];}
![Page 16: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/16.jpg)
☹
![Page 17: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/17.jpg)
use AnyEvent::HTTP;
http_get "http://osdc.tw/", sub { print $_[1] };
☺
![Page 18: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/18.jpg)
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
![Page 19: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/19.jpg)
AnyMQ
• Inspired by Tatsumaki::MessageQueue
• Refactored to support timeout handler, multiple subscription
• Support binding to other message queues using moose traits
• Available on CPAN and github
![Page 20: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/20.jpg)
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)
![Page 21: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/21.jpg)
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)
![Page 22: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/22.jpg)
Please help adding message queue
bindings!
![Page 23: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/23.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
![Page 24: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/24.jpg)
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, coined by Alex Russell
• Server push for real time notification
![Page 25: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/25.jpg)
Widely used
• gmail
• plurk
• facebook updates
![Page 26: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/26.jpg)
Lots of hacks!
• multi-part XHR
• forever iframe, with script callbacks
• spinning “loading” indicator for FF and IE
• number of connections limits
![Page 27: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/27.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
![Page 28: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/28.jpg)
Websocket
• HTML5 Websocket
• Bidirectional communication
ws = new WebSocket("ws://foo.com:5000”));ws.onmessage = function(ev) { ... }ws.send(....);
• Available in latest Chrome / Safari
![Page 29: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/29.jpg)
Putting Everything Together
![Page 30: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/30.jpg)
• PSGI, Plack
• AnyEvent, AnyMQ, AMQP
• Server-push, comet
• Websocket
• Web::Hippie, Web::Hippie::Pipe
![Page 31: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/31.jpg)
The Long Hair Web
![Page 32: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/32.jpg)
Hippie
![Page 33: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/33.jpg)
Hippie• Abstracts persistent connections:
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 }
Just a normal PSGI-app!
![Page 34: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/34.jpg)
Only Websocket and mxhr?
![Page 35: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/35.jpg)
Maybe Hippies should be
more relaxed...
![Page 36: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/36.jpg)
To relax a hippie, we need.....
![Page 37: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/37.jpg)
+
Hippie::Pipe
![Page 38: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/38.jpg)
Hippie::Pipe• Abstracts persistent bidirectional
connections: Websocket, MXHR, poll
enable "+Web::Hippie"; enable "+Web::Hippie::Pipe"; 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: # /init, /error, /message }
![Page 39: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/39.jpg)
Client side hpipe = new Hippie.Pipe(); $(hpipe) .bind(“ready”, function() { hpipe.send({type: ‘chat.join’, channel: ‘foo’, ident: ‘clkao’}) }) .bind(“disconnected”, function() {}) .bind(“message.chat.message”, function(e, data) {}); hpipe.init();
![Page 40: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/40.jpg)
DEMO
![Page 41: AnyMQ, Hippie, and the real-time web](https://reader034.fdocuments.in/reader034/viewer/2022052618/55493586b4c905144d8b46fa/html5/thumbnails/41.jpg)
Thank you!