2014/03/08(土)PerlでServer-Sent Events
サーバからPUSHされたイベントを受け取るやつ。(http://www.w3.org/TR/eventsource/)
最初リアルタイムで反映されなくて試行錯誤していたのですが、nginxの設定を変えたらリアルタイムで反映されるようになりました。(http://stackoverflow.com/questions/13672743/eventsource-server-sent-events-through-nginx)
コードは下の通りで「plackup」とかで立ち上げられます。
#!/usr/bin/env perl
use strict;
use warnings;
use AnyEvent;
use Time::Piece;
use HTTP::ServerEvent;
my $AFTER = 1;
my $INTERVAL = 1;
my $DURATION = 60 * 30; # 秒
my $html = do { local $/; <DATA> };
my $app = sub {
my $env = shift;
if ($env->{PATH_INFO} ne '/sse/events')
{
return [ 200, ['Content-Type', 'text/html'], [$html] ];
}
if ( ! $env->{"psgi.streaming"} )
{
my $err= "Server does not support streaming responses";
return [ 500, ['Content-Type', 'text/plain'], [$err] ];
}
return sub {
my $responder = shift;
my $writer = $responder->([ 200, [ 'Content-Type' => 'text/event-stream; charset=UTF-8' ] ]);
my $cnt = 0;
my $t; $t = AnyEvent->timer(
after => $AFTER,
interval => $INTERVAL,
cb => sub {
my $now = localtime->strftime('%Y-%m-%d %H:%M:%S');
my $event = HTTP::ServerEvent->as_string(
id => ++$cnt,
data => $now,
);
$writer->write($event);
undef $t if $cnt > $DURATION;
}
);
};
};
__DATA__
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Server-Sent Events</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</head>
<body>
<h1>Server-Sent Events</h1>
<div id="msg"></div>
<script>
var eventSource = new EventSource('/sse/events');
var msg = $("#msg");
eventSource.onmessage = function(e)
{
console.log("message");
console.log(e.data);
msg.prepend("<p>" + e.data + "</p>");
};
eventSource.onopen = function(e)
{
console.log("open");
};
eventSource.onerror = function(e)
{
console.log("error");
};
</script>
</body>