RLG-Web: begin converting to WebSockets.
Use WebSockets for watching, if the browser supports it. Functionality is not complete yet.
This commit is contained in:
parent
e143ac7d20
commit
aee00a29d5
2 changed files with 88 additions and 1 deletions
33
rlgterm.js
33
rlgterm.js
|
|
@ -82,7 +82,9 @@ var session = {
|
||||||
lname: null,
|
lname: null,
|
||||||
lcred: null,
|
lcred: null,
|
||||||
/* Whether the game is being played or just watched. */
|
/* Whether the game is being played or just watched. */
|
||||||
playing: false
|
playing: false,
|
||||||
|
/* WebSocket for communication */
|
||||||
|
sock: null
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The interval ID for checking the status of current games. */
|
/* The interval ID for checking the status of current games. */
|
||||||
|
|
@ -655,6 +657,10 @@ function startgame(game) {
|
||||||
function startwatching(gamenumber) {
|
function startwatching(gamenumber) {
|
||||||
if (session.id != null)
|
if (session.id != null)
|
||||||
return;
|
return;
|
||||||
|
if (WebSocket) {
|
||||||
|
wsWatch(gamenumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var wmsg = {"n": Number(gamenumber)};
|
var wmsg = {"n": Number(gamenumber)};
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.onerror = errHandler;
|
req.onerror = errHandler;
|
||||||
|
|
@ -692,6 +698,27 @@ function makeWatcher(n) {
|
||||||
return watcher;
|
return watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wsWatch(gamenumber) {
|
||||||
|
var sockurl = "ws://localhost:8080/watch/" + String(gamenumber);
|
||||||
|
var ws = new WebSocket(sockurl);
|
||||||
|
ws.onopen = function (event) {
|
||||||
|
session.id = true;
|
||||||
|
session.sock = ws;
|
||||||
|
message("You are now watching game #" + gamenumber + ".");
|
||||||
|
setmode("watch");
|
||||||
|
};
|
||||||
|
ws.onmessage = function (event) {
|
||||||
|
var msgObject = JSON.parse(event.data);
|
||||||
|
if (msgObject.t == 'd') {
|
||||||
|
writeData(msgObject.d);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onclose = function (event) {
|
||||||
|
session.sock = null;
|
||||||
|
gameover();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function formreg(ev) {
|
function formreg(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (session.id != null)
|
if (session.id != null)
|
||||||
|
|
@ -775,6 +802,10 @@ function logout() {
|
||||||
function stop() {
|
function stop() {
|
||||||
if (!session.id)
|
if (!session.id)
|
||||||
return;
|
return;
|
||||||
|
if (session.sock) {
|
||||||
|
session.sock.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.onerror = errHandler;
|
req.onerror = errHandler;
|
||||||
req.onreadystatechange = function () {
|
req.onreadystatechange = function () {
|
||||||
|
|
|
||||||
56
rlgwebd.js
56
rlgwebd.js
|
|
@ -11,6 +11,7 @@ var events = require('events');
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
var daemon = require(path.join(localModules, "daemon"));
|
var daemon = require(path.join(localModules, "daemon"));
|
||||||
var pty = require(path.join(localModules, "pty.js"));
|
var pty = require(path.join(localModules, "pty.js"));
|
||||||
|
var WebSocketServer = require(path.join(localModules, "websocket")).server;
|
||||||
|
|
||||||
/* Configuration variables */
|
/* Configuration variables */
|
||||||
// These first two files are NOT in the chroot.
|
// These first two files are NOT in the chroot.
|
||||||
|
|
@ -130,6 +131,8 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
* with a complete screen. */
|
* with a complete screen. */
|
||||||
this.framebuf = new Buffer(1024);
|
this.framebuf = new Buffer(1024);
|
||||||
this.frameoff = 0;
|
this.frameoff = 0;
|
||||||
|
/* List of WebSockets watching the game. */
|
||||||
|
this.watchsocks = [];
|
||||||
logins[lkey].sessions.push(this.sessid);
|
logins[lkey].sessions.push(this.sessid);
|
||||||
/* END setup */
|
/* END setup */
|
||||||
function ttyrec_chunk(datastr) {
|
function ttyrec_chunk(datastr) {
|
||||||
|
|
@ -168,6 +171,22 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
this.write = function(data) {
|
this.write = function(data) {
|
||||||
this.term.write(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 () {
|
this.term.on("exit", function () {
|
||||||
fs.unlink(ss.lock);
|
fs.unlink(ss.lock);
|
||||||
ss.record.end();
|
ss.record.end();
|
||||||
|
|
@ -354,6 +373,27 @@ function Player(gamename, lkey, dims, callback) {
|
||||||
this.session = new TermSession(gamename, lkey, dims, handlers);
|
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
|
/* Some functions which check whether a player is currently playing or
|
||||||
* has a saved game. Maybe someday they will provide information on
|
* has a saved game. Maybe someday they will provide information on
|
||||||
* the game. */
|
* the game. */
|
||||||
|
|
@ -1029,6 +1069,18 @@ 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 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 () {
|
function shutdown () {
|
||||||
httpServer.close();
|
httpServer.close();
|
||||||
httpServer.removeAllListeners('request');
|
httpServer.removeAllListeners('request');
|
||||||
|
|
@ -1066,6 +1118,7 @@ if (process.getuid() != 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpServer; // declare here so shutdown() can find it
|
var httpServer; // declare here so shutdown() can find it
|
||||||
|
var wsServer;
|
||||||
|
|
||||||
/* This could be nonblocking, but nothing else can start yet anyway. */
|
/* This could be nonblocking, but nothing else can start yet anyway. */
|
||||||
if (fs.existsSync(ctlsocket)) {
|
if (fs.existsSync(ctlsocket)) {
|
||||||
|
|
@ -1106,5 +1159,8 @@ ctlServer.listen(ctlsocket, function () {
|
||||||
httpServer.listen(httpPort);
|
httpServer.listen(httpPort);
|
||||||
tslog('rlgwebd running on port %d', httpPort);
|
tslog('rlgwebd running on port %d', httpPort);
|
||||||
setInterval(reaper, playtimeout / 4);
|
setInterval(reaper, playtimeout / 4);
|
||||||
|
wsServer = new WebSocketServer({"httpServer": httpServer});
|
||||||
|
wsServer.on("request", wsHandler);
|
||||||
|
tslog('WebSockets are online');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue