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





![: Amazon.co.jp: プラスティック・メモリーズ 1【完全生産限定版】(イベントチケット優先販売申込券付) [Blu-ray]](/lists/_9/B00VWX66E8.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 2【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66K2.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 3【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6MV0.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 4【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66IO.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 5【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6Y0E.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 6【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX69D6.jpg)


コメントする