Skip to content

Instantly share code, notes, and snippets.

@niratama
Created December 10, 2013 13:50
Show Gist options
  • Save niratama/7890854 to your computer and use it in GitHub Desktop.
Save niratama/7890854 to your computer and use it in GitHub Desktop.
Mojoliciousで各種ストリーミングのテスト
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub {
my $self = shift;
$self->render('index');
};
# XMLHttpRequest Streaming
get '/stream' => sub {
my $self = shift;
Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
$self->res->headers->cache_control('no-cache, max-age=0');
$self->res->headers->content_type('application/octet-stream');
my $id;
$id = Mojo::IOLoop->recurring(1 => sub {
my $message = 'time='.time."\n";
$self->write_chunk($message);
$self->app->log->debug($message);
});
$self->app->log->debug($id.':start');
$self->on(finish => sub {
$self->app->log->debug($id.':finish');
Mojo::IOLoop->remove($id);
});
$self->render_later;
};
# XDomainRequest Streaming
get '/xdrstream' => sub {
my $self = shift;
Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
$self->res->headers->header('Access-Control-Allow-Origin' => '*');
$self->res->headers->cache_control('no-cache, max-age=0');
$self->res->headers->content_type('text/plain');
my $id;
$id = Mojo::IOLoop->recurring(1 => sub {
my $message = 'time='.time."\n";
$self->write_chunk($message);
$self->app->log->debug($message);
});
$self->app->log->debug($id.':start');
$self->on(finish => sub {
$self->app->log->debug($id.':finish');
Mojo::IOLoop->remove($id);
});
$self->write_chunk(' 'x2048);
$self->render_later;
};
# EventSource
get '/events' => sub {
my $self = shift;
Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
$self->res->headers->cache_control('no-cache, max-age=0');
$self->res->headers->content_type('text/event-stream');
my $id;
$id = Mojo::IOLoop->recurring(1 => sub {
my $message = 'time='.time;
$self->write("data: $message\ndata: \n\n");
$self->app->log->debug($message);
});
$self->app->log->debug($id.':start');
$self->on(finish => sub {
$self->app->log->debug($id.':finish');
Mojo::IOLoop->remove($id);
});
$self->render_later;
};
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(function () {
var url = '/stream';
var messageLen = 0;
if ("XDomainRequest" in window) {
var xdr = new XDomainRequest();
xdr.onerror = function (e) {
console.log('error', e);
};
xdr.onload = function (e) {
console.log('load', e);
};
xdr.onprogress = function () {
console.log('progress');
$('#log').append('progress\n');
if (messageLen < xdr.responseText.length) {
var chunk = xdr.responseText.substring(messageLen, xdr.responseText.length);
console.log(messageLen, xdr.responseText.length, chunk);
$('#log').append(chunk);
messageLen = xdr.responseText.length;
}
};
xdr.open('GET', '/xdrstream');
xdr.send();
} else {
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function () {
if (xhr.readyState == 1) {
console.log('loading');
$('#log').append('loading\n');
} else if (xhr.readyState == 2 && xhr.status == 200) {
console.log('loaded');
$('#log').append('loaded\n');
} else if (xhr.readyState == 3) {
console.log('interactive');
$('#log').append('interactive\n');
if (messageLen < xhr.responseText.length) {
var chunk = xhr.responseText.substring(messageLen, xhr.responseText.length);
console.log(messageLen, xhr.responseText.length, chunk);
$('#log').append(chunk);
messageLen = xhr.responseText.length;
}
} else if (xhr.readyState == 4) {
console.log('complete');
$('#log').append('complete\n');
}
});
xhr.addEventListener('error', function (e) {
console.log('error', e, xhr.status, xhr.statusText);
$('#log').append('error:' + xhr.statusText);
});
xhr.open('GET', url, true);
xhr.send();
}
if ("EventSource" in window) {
var events = new EventSource('/events');
events.addEventListener('message', function (e) {
console.log(e.data);
$('#log2').append(e.data);
if (e.data === 'close') {
events.close();
}
});
events.addEventListener('open', function (e) {
console.log('open', e);
$('#log2').append('open\n');
});
events.addEventListener('error', function (e) {
console.log('error', e);
$('#log2').append('error\n');
if (events.readyState === EventSource.CONNECTING) {
// reconnecting
} else if (events.readyState === EventSource.CLOSED) {
// closed
}
});
} else {
$('#log2').append('not supported');
}
});
</script>
<style>
div.box {
display: inline-block;
width: 10em;
border: 1px solid red;
vertical-align: top;
}
</style>
</head>
<body>
<h1>stream test</h1>
<div>
<div class="box">Streaming<br/><pre id="log"></pre></div>
<div class="box">EventSource<br /><pre id="log2"></pre></div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment