Google ChromeウェブブラウザにMojolicious::LiteサーバからWebSocketで接続しリアルタイムでTwitterのストリームを表示する
スポンサードリンク
Twitter Streaming APIからの出力をリアルタイムにWebブラウザに表示する実装を作るにあたり、Mojolicious::LiteサーバとGoogle ChromeブラウザをWebSocketで接続すればいいと考え、実際にできるかどうか試してみました。
動画でイメージを見たほうが早いので、下記をどうぞ。
Mojoliciousの発音がこれでいいかは知らない。
Filename: test4-anony.pl
#!/usr/bin/perl use AnyEvent::Twitter::Stream; use Config::Pit; use DateTime; use Encode; use EV; use File::Spec; use FindBin::Real; use HTML::Entities; use Mojolicious::Lite; use Mojo::JSON; use URI::Escape; use utf8; use YAML; # consumer_keyが書かれたYAMLファイルを用意しておく my $keys = YAML::LoadFile( File::Spec->catdir( FindBin::Real::Bin(), '..', 'consumer_keys.yaml' ) ); # Config::Pit あらかじめ自分のディレクトリにtokenが書かれたYAML用意しておく my $pit = pit_get( 'twitter.com@CLCLCL' ); my $clients = {}; my $done = AnyEvent->condvar; my $listener = AnyEvent::Twitter::Stream->new( consumer_key => $keys->{consumer_key}, consumer_secret => $keys->{consumer_key_secret}, token => $pit->{access_token}, token_secret => $pit->{access_token_secret}, method => 'sample', #method => 'filter', #track => 'dtpstudy', on_tweet => sub { my $tweet = shift; my $user = $tweet->{user}{screen_name}; my $text = decode_entities($tweet->{text} || ''); my $lang = $tweet->{user}{lang} || ''; return if $lang ne 'ja'; # 日本語メッセージのみ選ぶ return unless $user && $text; $user =~ s/./*/g; $text =~ s/\@[^\s:]+/@****/g; $text =~ s/[^\s]+さん/****ちゃん/g; $text =~ s/[^\s]+ちゃん/****さん/g; $text =~ s/[^\s]+くん/****クン/g; $text =~ s{http://t.co/[\w\-]+}{http://t.co/******}g; print $user." : ".encode_utf8($text)."\n"; my $json = Mojo::JSON->new; my $dt = DateTime->now( time_zone => 'Asia/Tokyo'); my $str = $json->encode({ hms => $dt->hms, user => $user, text => $text, }); # utf8フラグが落ちる utf8::decode( $str ); # utf8フラグ付きに戻す for (keys %$clients) { $clients->{$_}->send_message( $str ); } }, on_error => sub { my $error = shift; warn "ERROR: $error"; $done->send; }, on_eof => sub { $done->send; }, ); get '/' => 'index'; websocket '/echo' => sub { my $self = shift; app->log->debug(sprintf 'Client connected: %s', $self->tx); my $id = sprintf "%s", $self->tx; $clients->{$id} = $self->tx; $self->on_message(); $self->on_finish( sub { app->log->debug('Client disconnected'); delete $clients->{$id}; } ); }; app->start; __DATA__ @@ index.html.ep <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Mojolicious + WebSocket + Twitter Streaming API</title> %= javascript '/js/jquery.js'; <script type="text/javascript"> $(function() { $('textarea').height( $('body').innerHeight() - $('article').position().top ); }); $(function () { var show = function (text) { var sel = 'textarea'; $(sel).val( text + "\n" + $(sel).val() ); }; var ws = new WebSocket('ws://' + location.host + '/echo'); ws.onopen = function () { console.log('Connection opened'); }; ws.onmessage = function (msg) { var res = JSON.parse(msg.data); show(res.user + ': ' + res.text); }; }); </script> <style type="text/css"> html, body { height: 98%; } h1 { font-size: 14px; } textarea { width: 100%; } </style> </head> <body> <header> <h1>Mojolicious + WebSocket + Twitter Streaming API</h1> </header> <article> <textarea></textarea> </article> </body> </html>
サーバを立ち上げるあたりが大変なのかもしれませんが、これでいろんなものが作れそうな気がしてきますよね。
参考にした:
Mojolicious::Lite で WebSocket を使ったチャットを作る - naoyaのはてなダイアリー [d.hatena.ne.jp]
M.C.P.C.: AnyEvent::Twitterなるものを知ったがSearch APIは使えないのかな←Search APIはないけれども、methodをFilterにして、trackにひっかけたい文字列を設定するんですね。
(2011-10-10 15:50追記)
このままだと、素の状態から構築したときEVモジュールが入っていないと動かないことが判明したので、use EV;を追加しました。
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3719
コメントする