SocketIOのサーバ側Perl実装のPocketIO。 Hachioji.pmが中心となって開発しているYairc(仮)でも使われているんで、 気になって触ってます。
実用的に使うにはPlackのMiddlewareとかAppを活用して他のWeb Application Frameworkのアプリと同居させるといいのかなぁーと なんとなく妄想してみる。そこで、Plack::App::URLMapのmountメソッドでPocketIOのHandlerとMojoliciousアプリのパスを分けて、簡単なイカ娘語変換のechoサンプルをつくってみる!といってもMojoliciousアプリの部分ってほとんど無いけど!
app.psgiはこんな感じっす。
use Mojo::Server::PSGI;
use File::Spec;
use File::Basename;
use lib File::Spec->catdir(dirname(__FILE__), 'lib');
use Plack::Builder;
use PocketIO;
my $psgi = Mojo::Server::PSGI->new( app_class => 'App::Web' );
my $app = sub { $psgi->run(@_) };
builder {
mount '/socket.io' => PocketIO->new( class => 'App::Handler', method => 'run' );
mount '/' => $app;
};
lib/App/Web.pmには普通にMojoliciousのルーティング等を書いて...
package App::Web;
use Mojo::Base 'Mojolicious';
sub startup {
my $self = shift;
my $r = $self->routes;
$r->route('/')->to('root#index');
}
1;
lib/App/Handler.pmには飛んできたテキストをイカ娘語変換して返すようにして...
package App::Handler;
use Acme::Ikamusume;
use strict;
use warnings;
sub new {
my $class = shift;
return bless {}, $class;
}
sub run {
my $self = shift;
return sub {
my $socket = shift;
$socket->on(
message => sub {
my $socket = shift;
my ($message) = @_;
$message = Acme::Ikamusume->geso($message);
$socket->send($message);
}
);
};
}
1;
publicディレクトリにjs等を配置する...
$ tree ./public/
./public/
└── js
├── WebSocketMain.swf
├── WebSocketMainInsecure.swf
├── app.js
└── socket.io.js
templates/root/index.html.ep にこうやって記述...
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="/js/socket.io.js"></script>
<script src="/js/app.js"></script>
</head>
<body>
<p>
<form>
<input type="text" />
<input type="submit" value="Send" />
</form>
</p>
<p id="output"></p>
</body>
</html>
public/js/app.jsはこんな感じ...
$(function(){
var socket = io.connect();
socket.on('message', function (data) {
$('#output').text(data);
});
$('form').submit(function(){
var message = $('input[type="text"]').val();
socket.send(message);
return false;
});
});
Twiggyでapp.psgiを立ち上げてみる...
$ twiggy app.psgi
ブラウザからテキストを入力してみると...

うまくいったじゃなイカ!!