Mercurial > hg > rlgwebd
diff rlgwebd.js @ 100:3dbfdaf62623
RLG-Web: begin converting to WebSockets.
Use WebSockets for watching, if the browser supports it. Functionality
is not complete yet.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Thu, 12 Jul 2012 22:16:15 -0700 |
parents | 597e9477b8ae |
children | e59d68082664 |
line wrap: on
line diff
--- a/rlgwebd.js Thu Jul 12 07:58:23 2012 -0700 +++ b/rlgwebd.js Thu Jul 12 22:16:15 2012 -0700 @@ -11,6 +11,7 @@ var child_process = require('child_process'); var daemon = require(path.join(localModules, "daemon")); var pty = require(path.join(localModules, "pty.js")); +var WebSocketServer = require(path.join(localModules, "websocket")).server; /* Configuration variables */ // These first two files are NOT in the chroot. @@ -130,6 +131,8 @@ * with a complete screen. */ this.framebuf = new Buffer(1024); this.frameoff = 0; + /* List of WebSockets watching the game. */ + this.watchsocks = []; logins[lkey].sessions.push(this.sessid); /* END setup */ function ttyrec_chunk(datastr) { @@ -168,6 +171,22 @@ this.write = function(data) { this.term.write(data); }; + // WebSocket watchers. + this.addWS = function (conn) { + this.watchsocks.push(conn); + }; + this.removeWS = function (conn) { + var i = this.watchsocks.indexOf(conn); + if (i >= 0) { + if (conn.connected) + conn.close(); + this.watchsocks.splice(i, 1); + return true; + } + else + return false; + }; + // Teardown. this.term.on("exit", function () { fs.unlink(ss.lock); ss.record.end(); @@ -354,6 +373,27 @@ this.session = new TermSession(gamename, lkey, dims, handlers); } +// Also known as WebSocketAndTermSessionClosureGlueFactory +function wsWatcher(conn, session) { + var ss = this; // is this even needed? + var dataH = function(buf) { + conn.sendUTF(JSON.stringify({"t": "d", "d": buf.toString("hex")})); + }; + var exitH = function() { + if (conn.connected) + conn.close(); + } + session.on('data', dataH); + session.on('exit', exitH); + conn.on('close', function(code, desc) { + session.removeListener('data', dataH); + session.removeListener('exit', exitH); + tslog("A WebSocket watcher has left game %d", session.sessid); + }); + conn.sendUTF(JSON.stringify({"t": "d", + "d": session.framebuf.toString("hex", 0, session.frameoff)})); +} + /* Some functions which check whether a player is currently playing or * has a saved game. Maybe someday they will provide information on * the game. */ @@ -1029,6 +1069,18 @@ } +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 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]); +} + function shutdown () { httpServer.close(); httpServer.removeAllListeners('request'); @@ -1066,6 +1118,7 @@ } var httpServer; // declare here so shutdown() can find it +var wsServer; /* This could be nonblocking, but nothing else can start yet anyway. */ if (fs.existsSync(ctlsocket)) { @@ -1106,5 +1159,8 @@ httpServer.listen(httpPort); tslog('rlgwebd running on port %d', httpPort); setInterval(reaper, playtimeout / 4); + wsServer = new WebSocketServer({"httpServer": httpServer}); + wsServer.on("request", wsHandler); + tslog('WebSockets are online'); });