anymq, hippie, and the real-time web

41
AnyMQ, Hippie and the real-time web OSDC.TW 2010 Taipei Chia-liang Kao [email protected]

Upload: clkao

Post on 06-May-2015

4.820 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: AnyMQ, Hippie, and the real-time web

AnyMQ, Hippieand the real-time web

OSDC.TW 2010 TaipeiChia-liang Kao [email protected]

Page 2: AnyMQ, Hippie, and the real-time web

高嘉良

Page 3: AnyMQ, Hippie, and the real-time web

clkao

Page 4: AnyMQ, Hippie, and the real-time web

Things I’ve been playing

with

Page 5: AnyMQ, Hippie, and the real-time web

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie:Pipe

Page 6: AnyMQ, Hippie, and the real-time web

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie::Pipe

Page 7: AnyMQ, Hippie, and the real-time web

Plack: Perl Web Superglue

Page 8: AnyMQ, Hippie, and the real-time web

PSGI

Page 9: AnyMQ, Hippie, and the real-time web

$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

$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

CGI.pmMUST DIE! ☠! ☠! ☠

Page 12: AnyMQ, Hippie, and the real-time web

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie::Pipe

Page 13: AnyMQ, Hippie, and the real-time web

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

Let’s try this in POE

Page 15: AnyMQ, Hippie, and the real-time web

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

Page 17: AnyMQ, Hippie, and the real-time web

use AnyEvent::HTTP;

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

Page 18: AnyMQ, Hippie, and the real-time web

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

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

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

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

Please help adding message queue

bindings!

Page 23: AnyMQ, Hippie, and the real-time web

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie::Pipe

Page 24: AnyMQ, Hippie, and the real-time web

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

Widely used

• gmail

• plurk

• facebook updates

Page 26: AnyMQ, Hippie, and the real-time web

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

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie::Pipe

Page 28: AnyMQ, Hippie, and the real-time web

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

Putting Everything Together

Page 30: AnyMQ, Hippie, and the real-time web

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

• Web::Hippie, Web::Hippie::Pipe

Page 31: AnyMQ, Hippie, and the real-time web

The Long Hair Web

Page 32: AnyMQ, Hippie, and the real-time web

Hippie

Page 33: AnyMQ, Hippie, and the real-time web

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

Only Websocket and mxhr?

Page 35: AnyMQ, Hippie, and the real-time web

Maybe Hippies should be

more relaxed...

Page 36: AnyMQ, Hippie, and the real-time web

To relax a hippie, we need.....

Page 37: AnyMQ, Hippie, and the real-time web

+

Hippie::Pipe

Page 38: AnyMQ, Hippie, and the real-time web

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

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

DEMO

Page 41: AnyMQ, Hippie, and the real-time web

Thank you!