http://d.hatena.ne.jp/memememomo/20100408/1270679837
こちらのプログラムの結果をTatsumakiを使用してブラウザで表示するようにしました。
app.psgi
ここでは、ディスパッチ設定を行ないます。
「http://localhost:5000/{トラックワード}」でアクセスしてきた時の設定と
「http://localhost:5000/{トラックワード}/poll/」でアクセスしてきた時の設定を行ないます。
後者はjavascriptのイベントループ内でアクセスされます。
package main; use Tatsumaki::Application; use File::Basename; my $word = '[\w\.\-]+'; my $app = Tatsumaki::Application->new([ "/($word)/poll/" => 'TweetHandler', "/($word)" => 'HtmlHandler', ]); $app->template_path( dirname(__FILE__) . "/template" ); $app->static_path( dirname(__FILE__) . "/static" ); return $app;
my $app = Tatsumaki::Application->new([ ... ]);
の部分で、どのアクセスにどのモジュールを使用するかを設定しています。
HtmlHandler
「http://localhost:5000/{トラックワード}」でアクセスしてきた時の処理を書きます。
package HtmlHandler; use Moose; extends 'Tatsumaki::Handler'; sub get { my $self = shift; my ( $track ) = @_; $self->render( 'index.html' ); } no Moose;
ツイートを表示するページを表示します。
テンプレートは下記のようなもの。
% my $track = $_[0]->{handler}->args->[0]; <html> <head> <title> Track Word 「<%= $track %>」</title> <script type="text/javascript" src="static/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="static/jquery.ev.js"></script> <script type="text/javascript"> jQuery( function ($) { $.ev.loop('/' + <%= $track %>' + '/poll/' + '?session=' + Math.random(), { tweet : function(ev) { if(! ev.tweet.user || ! ev.tweet.text) return; $( "#tweets" ).prepend( ev.tweet.user.screen_name + ": " + ev.tweet.text + "<br>" ); }, message : function(ev) { $( "#tweets" ).prepend( '<span style="color: #f00;">' + ev.text + "</span><br>" ); } }); }); </script> </head> <body> <h1>Track Word 「<%= $track %>」 </h1> <div id="tweets"></div> </body> </html>
ツイートを表示する領域を準備します。
また、javascriptでイベントループを回して、サーバ側にアクセスします。
TweetHandler
javascriptからのアクセスに対して、処理します。
リクエストを受け取ると、AnyEventでのイベントループが周り始めます。
package TweetHandler; use Moose; use Config::Pit; use AnyEvent::Twitter::Stream; use Tatsumaki::MessageQueue; use Tatsumaki::Error; extends 'Tatsumaki::Handler'; __PACKAGE__->asynchronous(1); my ($username, $password) = do { @{ Config::Pit::get( 'twitter.com', require => { 'username' => 'memememomo', })}{ qw/username password/ }; }; my %streams; sub create_stream { my $self = shift; my ( $track ) = @_; my $mq = Tatsumaki::MessageQueue->instance( $track ); $streams{$track} ||= AnyEvent::Twitter::Stream->new( username => $username, password => $password, method => 'filter', track => $track, on_tweet => sub { my $tweet = shift; $mq->publish( { type => 'tweet', tweet => $tweet, } ); }, on_error => sub { my $error = join ',', @_; $mq->publish( { type => 'message', text => $error, } ); delete $streams{ $track }; }, on_eof => sub { $mq->publish( { type => 'message', text => 'disconnected', } ); delete $streams{ $track }; }, ); } sub get { my $self = shift; my ( $track ) = @_; my $session = $self->request->param('session') or Tatsumaki::Error::HTTP->throw(500, "'session' needed"); $streams{ $track } or $self->create_stream( $track ); my $mq = Tatsumaki::MessageQueue->instance( $track ); $mq->poll_once( $session, sub { my @events_published = @_; $self->write( \@events_published ); $self->finish; }); } no Moose;
起動
「plackup app.psgi」で起動して、「http://localhost:5000/perl」でアクセスしてみます。
そうするとツイートに「perl」を含んだものがずらずらと流れるように出力されると思います。