anymq, hippie, and the real-time web

Post on 06-May-2015

4.817 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

AnyMQ, Hippieand the real-time web

OSDC.TW 2010 TaipeiChia-liang Kao clkao@clkao.org

高嘉良

clkao

Things I’ve been playing

with

• 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: Perl Web Superglue

PSGI

$env

[ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ], ]

$env->{PATH_INFO}

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

$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

CGI.pmMUST DIE! ☠! ☠! ☠

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

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

AnyEvent

• event-driven programming, painless

• compatible with many other event loops

use AnyEvent::HTTP;

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

Let’s try this in 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://osdc.tw/", 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

• 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

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)

Please help adding message queue

bindings!

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

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

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

Widely used

• gmail

• plurk

• facebook updates

Lots of hacks!

• multi-part XHR

• forever iframe, with script callbacks

• spinning “loading” indicator for FF and IE

• number of connections limits

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

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

Websocket

• HTML5 Websocket

• Bidirectional communication

ws = new WebSocket("ws://foo.com:5000”));ws.onmessage = function(ev) { ... }ws.send(....);

• Available in latest Chrome / Safari

Putting Everything Together

• PSGI, Plack

• AnyEvent, AnyMQ, AMQP

• Server-push, comet

• Websocket

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

The Long Hair Web

Hippie

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!

Only Websocket and mxhr?

Maybe Hippies should be

more relaxed...

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

+

Hippie::Pipe

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 }

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();

DEMO

Thank you!

top related