RLGWebD: fix simultaneous watcher bugs.
WebSockets should now only receive the intended data, no matter how many of them there are or what they are doing. They should...
This commit is contained in:
parent
6373e70361
commit
60b83c4944
1 changed files with 35 additions and 31 deletions
66
rlgwebd.js
66
rlgwebd.js
|
|
@ -125,6 +125,8 @@ function TermSession(gname, pname, wsReq) {
|
||||||
this.framebuf = new Buffer(1024);
|
this.framebuf = new Buffer(1024);
|
||||||
this.frameoff = 0;
|
this.frameoff = 0;
|
||||||
this.playerconn = wsReq.accept(null, wsReq.origin);
|
this.playerconn = wsReq.accept(null, wsReq.origin);
|
||||||
|
/* Array for watcher connections. */
|
||||||
|
this.watchers = [];
|
||||||
/* END setup */
|
/* END setup */
|
||||||
function ttyrec_chunk(datastr) {
|
function ttyrec_chunk(datastr) {
|
||||||
ss.lasttime = new Date();
|
ss.lasttime = new Date();
|
||||||
|
|
@ -138,9 +140,13 @@ function TermSession(gname, pname, wsReq) {
|
||||||
ss.record.write(chunk);
|
ss.record.write(chunk);
|
||||||
ss.framepush(buf);
|
ss.framepush(buf);
|
||||||
/* Send to the player. */
|
/* Send to the player. */
|
||||||
var msg = {"t": "d", "d": buf.toString("hex")};
|
var msg = JSON.stringify({"t": "d", "d": buf.toString("hex")});
|
||||||
ss.playerconn.sendUTF(JSON.stringify(msg));
|
ss.playerconn.sendUTF(msg);
|
||||||
/* For the benefit of watchers. */
|
/* Send to any watchers. */
|
||||||
|
for (var i = 0; i < ss.watchers.length; i++) {
|
||||||
|
if (ss.watchers[i].connected)
|
||||||
|
ss.watchers[i].sendUTF(msg);
|
||||||
|
}
|
||||||
ss.emit('data', buf);
|
ss.emit('data', buf);
|
||||||
}
|
}
|
||||||
this.term.on("data", ttyrec_chunk);
|
this.term.on("data", ttyrec_chunk);
|
||||||
|
|
@ -174,6 +180,12 @@ function TermSession(gname, pname, wsReq) {
|
||||||
var tag = ss.tag();
|
var tag = ss.tag();
|
||||||
fs.unlink(ss.lock);
|
fs.unlink(ss.lock);
|
||||||
ss.record.end();
|
ss.record.end();
|
||||||
|
var watchsocks = ss.watchers;
|
||||||
|
ss.watchers = [];
|
||||||
|
for (var i = 0; i < watchsocks.length; i++) {
|
||||||
|
if (watchsocks[i].connected)
|
||||||
|
watchsocks[i].close();
|
||||||
|
}
|
||||||
if (ss.playerconn.connected) {
|
if (ss.playerconn.connected) {
|
||||||
ss.playerconn.sendUTF(JSON.stringify({"t": "q"}));
|
ss.playerconn.sendUTF(JSON.stringify({"t": "q"}));
|
||||||
ss.playerconn.close();
|
ss.playerconn.close();
|
||||||
|
|
@ -207,6 +219,25 @@ function TermSession(gname, pname, wsReq) {
|
||||||
}
|
}
|
||||||
this.playerconn.on('message', messageH);
|
this.playerconn.on('message', messageH);
|
||||||
this.playerconn.on('close', this.close);
|
this.playerconn.on('close', this.close);
|
||||||
|
/* To attach a watcher. */
|
||||||
|
this.attach = function (wsReq) {
|
||||||
|
var conn = wsReq.accept(null, wsReq.origin);
|
||||||
|
conn.sendUTF(JSON.stringify({
|
||||||
|
"t": "w", "w": this.w, "h": this.h, "p": this.pname,
|
||||||
|
"g": this.game.uname
|
||||||
|
}));
|
||||||
|
conn.sendUTF(JSON.stringify({"t": "d",
|
||||||
|
"d": this.framebuf.toString("hex", 0, this.frameoff)}));
|
||||||
|
conn.on('close', function () {
|
||||||
|
/* 'this' is the connection when triggered */
|
||||||
|
var n = ss.watchers.indexOf(this);
|
||||||
|
if (n >= 0) {
|
||||||
|
ss.watchers.splice(n, 1);
|
||||||
|
tslog("A WebSocket watcher has left game %s", ss.tag());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.watchers.push(conn);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
TermSession.prototype = new events.EventEmitter();
|
TermSession.prototype = new events.EventEmitter();
|
||||||
|
|
||||||
|
|
@ -316,32 +347,6 @@ function DglSession(filename) {
|
||||||
}
|
}
|
||||||
DglSession.prototype = new events.EventEmitter();
|
DglSession.prototype = new events.EventEmitter();
|
||||||
|
|
||||||
// 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);
|
|
||||||
if (session.tag() in sessions)
|
|
||||||
tslog("A WebSocket watcher has left game %s", session.tag());
|
|
||||||
});
|
|
||||||
conn.sendUTF(JSON.stringify({
|
|
||||||
"t": "w", "w": session.w, "h": session.h,
|
|
||||||
"p": session.pname, "g": session.game.uname
|
|
||||||
}));
|
|
||||||
conn.sendUTF(JSON.stringify({"t": "d",
|
|
||||||
"d": session.framebuf.toString("hex", 0, session.frameoff)}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function wsStartGame(wsReq) {
|
function wsStartGame(wsReq) {
|
||||||
var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/);
|
var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/);
|
||||||
if (!playmatch[1] || !(playmatch[1] in games)) {
|
if (!playmatch[1] || !(playmatch[1] in games)) {
|
||||||
|
|
@ -1009,8 +1014,7 @@ function wsHandler(wsRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var tsession = sessions[watchmatch[1]];
|
var tsession = sessions[watchmatch[1]];
|
||||||
var conn = wsRequest.accept(null, wsRequest.origin);
|
tsession.attach(wsRequest);
|
||||||
new wsWatcher(conn, tsession);
|
|
||||||
tslog("Game %s is being watched via WebSockets", tsession.tag());
|
tslog("Game %s is being watched via WebSockets", tsession.tag());
|
||||||
}
|
}
|
||||||
else if (playmatch !== null) {
|
else if (playmatch !== null) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue