Created
April 2, 2011 05:23
-
-
Save Cside/899250 to your computer and use it in GitHub Desktop.
websocket_test.pl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!perl | |
use strict; | |
use warnings; | |
use Plack::Builder; | |
use Plack::Request; | |
use Plack::Middleware::WebSocket; | |
use AnyEvent; | |
use AnyEvent::Handle; | |
use Coro; | |
use Coro::LWP; | |
use Furl; | |
my $furl = Furl->new; | |
my @coros; | |
my @urls = ( | |
'http://b.hatena.ne.jp/', | |
'http://c.hatena.ne.jp/', | |
'http://a.hatena.ne.jp/', | |
'http://h.hatena.ne.jp/', | |
'http://ugomemo.hatena.ne.jp/', | |
); | |
my $DATA = do { local $/; scalar <DATA> }; | |
my $app = sub { | |
my $env = shift; | |
my $req = Plack::Request->new($env); | |
my $res = $req->new_response(200); | |
if (not $env->{'psgi.streaming'}) { | |
die 'this handler does not support psgi.streaming'; | |
} | |
if ($req->path eq '/') { | |
my $data = $DATA; | |
$data =~ s/{{{HOST}}}/$env->{HTTP_HOST}/g; | |
$res->content_type('text/html; charset=utf-8'); | |
$res->content($data); | |
} | |
elsif ($req->path eq '/req') { | |
if (my $fh = $env->{'websocket.impl'}->handshake) { | |
my $handle = AnyEvent::Handle->new(fh => $fh); | |
return sub { | |
my $respond = shift; | |
on_read $handle sub { | |
shift->push_read( | |
'AnyEvent::Handle::Message::WebSocket', | |
sub { | |
my $msg = $_[1]; | |
if ($msg eq 'fire-event') { | |
concurrent_get($handle); | |
} | |
}, | |
); | |
}; | |
on_error $handle sub { | |
warn "error: $_[2]"; | |
$respond->([ | |
500, [ 'Content-Type', 'text/plain' ], [ "error: $_[2]" ], | |
]); | |
}; | |
}; | |
} | |
$res->code($env->{'websocket.impl'}->error_code); | |
} | |
else { | |
$res->code(404); | |
} | |
return $res->finalize; | |
}; | |
sub concurrent_get { | |
my $handle = shift; | |
my $count = 0; | |
my $push_write = sub { | |
my $msg = shift; | |
$handle->push_write( | |
'AnyEvent::Handle::Message::WebSocket', | |
$msg, | |
); | |
}; | |
for (1 .. scalar(@urls)) { | |
my $i = $_; | |
my $url = $urls[$i - 1]; | |
push @coros, async { | |
my $res = $furl->get($url); | |
$push_write->("[$i]$url: ".$res->status_line); | |
$count++; | |
if ($count == scalar(@urls)) { | |
$push_write->("all requests finished"); | |
} | |
}; | |
} | |
} | |
builder { | |
enable 'WebSocket'; | |
$app; | |
}; | |
__DATA__ | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Plack::Middleware::WebSocket</title> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> | |
<style type="text/css"> | |
#log { | |
border: 1px solid #DDD; | |
padding: 0.5em; | |
} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
function log (msg) { | |
$('#log').text($('#log').text() + msg + "\n"); | |
} | |
$(function () { | |
var ws = new WebSocket('ws://{{{HOST}}}/req'); | |
log('WebSocket start'); | |
ws.onopen = function () { | |
log('connected'); | |
}; | |
ws.onmessage = function (ev) { | |
log('received: ' + ev.data); | |
}; | |
ws.onerror = function (ev) { | |
log('error: ' + ev.data); | |
} | |
ws.onclose = function (ev) { | |
log('closed'); | |
} | |
$('#button').click(function() { | |
var data = 'fire-event'; | |
ws.send(data); | |
log('sent concurrent request'); | |
return false; | |
}); | |
}); | |
</script> | |
<button id="button"> | |
Start Concurrent Request | |
</button> | |
<pre id="log"></pre> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment