use CGI;
use Linux::Inotify2;
use AnyEvent;
+use IPC::ShareLite;
+use Storable;
use strict;
use warnings;
cb => sub { $cv->send; },
);
+my $unique = $cgi->param('unique');
+our $num_viewers = count_viewers($unique);
+
# Yes, this is reinventing If-Modified-Since, but browsers are so incredibly
# unpredictable on this, so blargh.
my $ims = 0;
$cv->recv;
output();
+sub count_viewers {
+ my $unique = shift;
+ my $time = time;
+ my $share = IPC::ShareLite->new(
+ -key => 'RGLT',
+ -create => 'yes',
+ -destroy => 'no',
+ -size => 1048576,
+ ) or die "IPC::ShareLite: $!";
+ $share->lock(IPC::ShareLite::LOCK_EX);
+ my $viewers = {};
+ eval {
+ $viewers = Storable::thaw($share->fetch());
+ };
+ $viewers->{$unique} = time;
+
+ # Go through and remove old viewers, and count them at the same time.
+ my $num_viewers = 0;
+ while (my ($key, $value) = each %$viewers) {
+ if ($time - $value > 60) {
+ delete $viewers->{$key};
+ } else {
+ ++$num_viewers;
+ }
+ }
+
+ $share->store(Storable::freeze($viewers));
+ $share->unlock();
+
+ return $num_viewers;
+}
+
sub output {
open my $fh, "<", $json_filename
or die "$json_filename: $!";
print CGI->header(-type=>'text/json',
-x_remoteglot_last_modified=>$time,
+ -x_remoteglot_num_viewers=>$num_viewers,
-access_control_allow_origin=>'http://analysis.sesse.net',
- -access_control_expose_headers=>'X-Remoteglot-Last-Modified',
+ -access_control_expose_headers=>'X-Remoteglot-Last-Modified, X-Remoteglot-Num-Viewers',
-expires=>'now');
print $data;
}
}
#score {
font-size: x-large;
+ margin-top: 0;
}
.window {
position: absolute;
.black-3c85d.nonuglyhighlight {
background-color: #9ab6a6;
}
-#board {
- display: block;
- float: left;
+#boardcontainer {
width: 400px;
margin-right: 1em;
margin-bottom: 1em;
+ float: left;
+}
+#board {
+ display: block;
+ width: 100%;
padding: 0;
}
+#numviewers {
+ display: block;
+ width: 100%;
+ text-align: center;
+ font-size: smaller;
+ margin-top: 0.5em;
+ margin-bottom: 0;
+}
#analysis {
display: block;
min-width: 400px;
/* If the board is too wide for the screen, shrink it to fit,
* and then put the analysis below. */
@media all and (max-width: 400px) {
- #board {
+ #boardcontainer {
width: 100%;
float: none;
}
/* If there is almost space for the analysis, shrink the board a bit, too. */
@media all and (min-width: 500px) and (max-width: 810px) {
- #board {
+ #boardcontainer {
float: left;
width: 50%;
}
</head>
<body>
<h1 id="headline">Analysis</h1>
-<div id="board"></div>
+<div id="boardcontainer">
+ <div id="board"></div>
+ <p id="numviewers"></p>
+</div>
<div id="analysis">
<p id="score">Score:</p>
<p><strong>PV:</strong> <span id="pv"></span></p>
var ims = 0;
var highlight_from = undefined;
var highlight_to = undefined;
+var unique = Math.random();
var request_update = function(board, first) {
$.ajax({
- //url: "http://analysis.sesse.net/analysis.pl?first=" + first
- url: "http://analysis.sesse.net:5000/analysis.pl?ims=" + ims
+ url: "http://analysis.sesse.net/analysis.pl?ims=" + ims + "&unique=" + unique
+ //url: "http://analysis.sesse.net:5000/analysis.pl?ims=" + ims + "&unique=" + unique
}).done(function(data, textstatus, xhr) {
ims = xhr.getResponseHeader('X-Remoteglot-Last-Modified');
- update_board(board, data);
+ var num_viewers = xhr.getResponseHeader('X-Remoteglot-Num-Viewers');
+ update_board(board, data, num_viewers);
});
}
}
}
-var update_board = function(board, data) {
+var update_board = function(board, data, num_viewers) {
// The headline.
var headline = 'Analysis';
if (data.position.last_move !== 'none') {
$("#headline").text(headline);
+ if (num_viewers === null) {
+ $("#numviewers").text("");
+ } else if (num_viewers == 1) {
+ $("#numviewers").text("You are the only current viewer");
+ } else {
+ $("#numviewers").text(num_viewers + " current viewers");
+ }
+
// The score.
if (data.score !== null) {
$("#score").text(data.score);