RLG-Web server: send status events over WebSockets.

A WebSocket connection to /status will be sent periodic listings, along
with notifications of the beginning and end of games.
This commit is contained in:
John "Elwin" Edwards 2012-07-13 22:26:20 -07:00
parent 4174840c3e
commit bec02aea9e

View file

@ -62,6 +62,7 @@ var sessions = {};
var clients = {};
var allowlogin = true;
var nextsession = 0;
var gamemux = new events.EventEmitter();
/* Constructor. A TermSession handles a pty and the game running on it.
* game: (String) Name of the game to launch.
@ -118,6 +119,7 @@ function TermSession(game, lkey, dims, handlers) {
tslog("%s playing %s (index %d, pid %d)", this.pname, this.game.uname,
this.sessid, this.term.pid);
this.emit('open', true, this.sessid);
gamemux.emit('begin', this.sessid, this.pname, this.game.uname);
/* Set up the lockfile and ttyrec */
var ts = timestamp();
var progressdir = "/dgldir/inprogress-" + this.game.uname;
@ -177,6 +179,7 @@ function TermSession(game, lkey, dims, handlers) {
var id = ss.sessid;
delete sessions[id];
tslog("Game %s ended.", id);
gamemux.emit('end', id);
});
this.close = function () {
this.term.kill('SIGHUP');
@ -1062,15 +1065,54 @@ function webHandler(req, res) {
}
function wsHandler(wsRequest) {
var urlmatch = wsRequest.resource.match(/^\/watch\/([0-9]*)$/);
if (urlmatch !== null && urlmatch[1] && Number(urlmatch[1]) in sessions) {
var tsession = sessions[Number(urlmatch[1])];
var watchmatch = wsRequest.resource.match(/^\/watch\/([0-9]*)$/);
if (watchmatch !== null) {
if (watchmatch[1] && Number(watchmatch[1]) in sessions) {
var tsession = sessions[Number(watchmatch[1])];
var conn = wsRequest.accept(null, wsRequest.origin);
new wsWatcher(conn, tsession);
tslog("Game %d is being watched via WebSockets", tsession.sessid);
}
else
wsRequest.reject(404, errorcodes[7]);
}
else if (wsRequest.resource == "/status") {
var conn = wsRequest.accept(null, wsRequest.origin);
new wsWatcher(conn, tsession);
tslog("Game %d is being watched via WebSockets", tsession.sessid);
var tell = function () {
getStatus(function (info) {
info["t"] = "t";
conn.sendUTF(JSON.stringify(info));
});
}
var beginH = function (n, name, game) {
conn.sendUTF(JSON.stringify({"t": "b", "n": n, "p": name, "g": game}));
};
var listH = function (list) {
conn.sendUTF(JSON.stringify(list));
};
var endH = function (n) {
conn.sendUTF(JSON.stringify({"t": "e", "n": n}));
};
gamemux.on('begin', beginH);
gamemux.on('list', listH);
gamemux.on('end', endH);
conn.on('message', tell);
conn.on('close', function () {
gamemux.removeListener('begin', beginH);
gamemux.removeListener('list', listH);
gamemux.removeListener('end', endH);
});
tell();
}
else
wsRequest.reject(404, errorcodes[7]);
wsRequest.reject(404, "No such resource.");
}
function pushStatus() {
getStatus(function(info) {
info["t"] = "t";
gamemux.emit('list', info);
});
}
function shutdown () {
@ -1154,5 +1196,6 @@ ctlServer.listen(ctlsocket, function () {
wsServer = new WebSocketServer({"httpServer": httpServer});
wsServer.on("request", wsHandler);
tslog('WebSockets are online');
setInterval(pushStatus, 4000);
});