Mercurial > hg > rlgwebd
changeset 159:a613380ffdc2
RLGWebD: excise polling.
WebSockets are supported nearly everywhere now.
Listing current games and watching them are still broken.
| author | John "Elwin" Edwards |
|---|---|
| date | Sat, 03 Jan 2015 15:23:04 -0500 |
| parents | 9961a538c00e |
| children | ed837da65e5f |
| files | rlgterm.js rlgwebd.js |
| diffstat | 2 files changed, 36 insertions(+), 666 deletions(-) [+] |
line wrap: on
line diff
--- a/rlgterm.js Thu Jan 01 15:56:22 2015 -0500 +++ b/rlgterm.js Sat Jan 03 15:23:04 2015 -0500 @@ -1,60 +1,5 @@ /* rlgterm.js: Roguelike Gallery's driver for termemu.js */ -// A state machine that keeps track of polling the server. -var ajaxstate = { - state: 0, - timerID: null, - clear: function () { - if (this.timerID != null) { - window.clearTimeout(this.timerID); - this.timerID = null; - } - }, - set: function (ms) { - this.clear(); - this.timerID = window.setTimeout(getData, ms); - }, - gotdata: function () { - this.set(1000); - this.state = 1; - }, - gotnothing: function () { - if (this.state == 0) { - this.set(1000); - this.state = 1; - } - else if (this.state < 4) { - this.set(4000); - this.state++; - } - else if (session.playing) { - if (this.state < 8) { - this.set(15000); - this.state++; - } - else { - /* It's been over a minute. Stop polling. */ - this.clear(); - } - } - else { - /* If watching, it can't stop polling entirely, because there - * are no POST events to start it up again. */ - this.set(10000); - } - }, - posted: function (wasdata) { - if (wasdata) { - this.set(1000); - this.state = 1; - } - else { - this.set(200); - this.state = 0; - } - } -}; - /* Data on the available games. */ var games = { "rogue3": { @@ -81,7 +26,7 @@ var session = { /* The session id assigned by the server. */ - id: null, + connect: false, /* Login name and key are now in sessionStorage. */ /* Whether the game is being played or just watched. */ playing: false, @@ -165,119 +110,15 @@ return; } -/* State for sending and receiving messages. */ -var nsend = 0; // The number of the next packet to send. -var nrecv = 0; // The next packet expected. -var msgQ = []; // Queue for out-of-order messages. - -/* Processes a message from the server, returning true or false if it was a - * data message with or without data, null if not data. - * All non-special responseTexts should be handed directly to this function. - */ -function processMsg(msg) { - var msgDicts; - var havedata = null; // eventual return value - try { - msgDicts = JSON.parse(msg); - } catch (e) { - if (e instanceof SyntaxError) - return null; - } - if (msgDicts.length === 0) - return false; - for (var j = 0; j < msgDicts.length; j++) { - if (!msgDicts[j].t) - continue; - else if (msgDicts[j].t == "E") { - if (msgDicts[j].c == 1 || msgDicts[j].c == 6 || msgDicts[j].c == 7) { - gameover(); - if (msgDicts[j].c == 1) { - logout(); - } - } - debug(1, "Server error: " + msgDicts[j].s); - } - // A data message - else if (msgDicts[j].t == "d") { - if (msgDicts[j].n === nrecv) { - writeData(msgDicts[j].d); - nrecv++; - /* Process anything in the queue that's now ready. */ - var next; - while ((next = msgQ.shift()) !== undefined) { - writeData(next.d); - nrecv++; - } - } - else if (msgDicts[j].n > nrecv) { - /* The current message comes after one still missing. Queue this one - * for later use. */ - debug(1, "Got packet " + msgDicts[j].n + ", expected " + nrecv); - msgQ[msgDicts[j].n - nrecv - 1] = msgDicts[j]; - } - else { - /* This message's number was encountered previously. */ - debug(1, "Discarding packet " + msgDicts[j].n + ", expected " + nrecv); - } - havedata = true; - } - else if (msgDicts[j].t == "T") { - setTitle(msgDicts[j].d); - } - else if (msgDicts[j].t == "q") { - gameover(); - } - else { - debug(1, "Unrecognized server message " + msg); - } - } - return havedata; -} - -function getData() { - if (session.id == null) - return; - var datareq = new XMLHttpRequest(); - var msg = JSON.stringify({"id": session.id, "t": "n"}); - datareq.onerror = errHandler; - datareq.onreadystatechange = function () { - if (datareq.readyState == 4 && datareq.status == 200) { - var wasdata = processMsg(datareq.responseText); - if (wasdata != null) { - if (wasdata) - ajaxstate.gotdata(); - else - ajaxstate.gotnothing(); - } - return; - } - }; - datareq.open('POST', '/feed', true); - datareq.send(msg); - return; -} - -function postResponseHandler() { - if (this.readyState == 4 && this.status == 200) { - // We might want to do something with wasdata someday. - var wasdata = processMsg(this.responseText); - ajaxstate.posted(); - return; - } -} - function errHandler() { message("Unable to connect to the server.", "warn"); } function sendback(str) { /* For responding to terminal queries. */ - var msgDict = {"id": session.id, "t": "d", "n": nsend++, "d": str}; - var datareq = new XMLHttpRequest(); - datareq.onerror = errHandler; - datareq.onreadystatechange = postResponseHandler; - datareq.open('POST', '/feed', true); - datareq.send(JSON.stringify(msgDict)); + if (session.sock) { + session.sock.send(JSON.stringify({"t": "d", "d": str})); + } return; } @@ -323,14 +164,7 @@ if (session.sock) { session.sock.send(JSON.stringify({"t": "d", "d": code})); } - else { - var datareq = new XMLHttpRequest(); - var msgDict = {"id": session.id, "t": "d", "n": nsend++, "d": code}; - datareq.onerror = errHandler; - datareq.onreadystatechange = postResponseHandler; - datareq.open('POST', '/feed', true); - datareq.send(JSON.stringify(msgDict)); - } + /* Otherwise it is disconnected */ return; } @@ -386,14 +220,6 @@ if (session.sock) { session.sock.send(JSON.stringify({"t": "d", "d": keystr})); } - else { - var datareq = new XMLHttpRequest(); - var msgDict = {"id": session.id, "t": "d", "n": nsend++, "d": keystr}; - datareq.onerror = errHandler; - datareq.onreadystatechange = postResponseHandler; - datareq.open('POST', '/feed', true); - datareq.send(JSON.stringify(msgDict)); - } return; } @@ -426,8 +252,8 @@ break; } if (!window.WebSocket) { - message("Your browser does not support WebSockets. You can still play, " + - "but it will be slower, and may not work in the future.", "warn"); + message("Your browser does not support WebSockets. " + + "This Web app will not work.", "warn"); } return; } @@ -454,8 +280,7 @@ function formlogin(ev) { ev.preventDefault(); - if (session.id != null) - return; + /* What to do if logged in already? */ var loginmsg = {}; loginmsg["name"] = document.getElementById("input_name").value; loginmsg["pw"] = document.getElementById("input_pw").value; @@ -490,6 +315,7 @@ return; } +/* FIXME game list API has changed */ function tableCurrent(gamelist) { var gamediv = document.getElementById("gametable"); while (gamediv.children.length > 2) @@ -533,7 +359,7 @@ function wsCurrent() { if (!window.WebSocket) return; - if (session.id) { + if (session.connect) { /* Don't bother with status if already playing/watching. */ if (statsock) { statsock.close(); @@ -569,11 +395,12 @@ } } +/* FIXME gamelist API has changed */ function getcurrent(clear) { if (window.WebSocket) { return; } - if (session.id || clear) { + if (session.connect || clear) { if (statInterval) { window.clearInterval(statInterval); statInterval = null; @@ -608,7 +435,7 @@ } function getchoices() { - if (session.id != null || !("lcred" in sessionStorage)) + if (session.connect || !("lcred" in sessionStorage)) return; var req = new XMLHttpRequest(); req.onerror = errHandler; @@ -680,62 +507,6 @@ return starter; } -function startgame(game) { - if (session.id != null || !("lcred" in sessionStorage)) - return; - if (window.WebSocket) { - wsStart(game); - return; - } - var smsg = {}; - smsg["key"] = sessionStorage.getItem("lcred"); - smsg["game"] = game.uname; - smsg["h"] = 24; - smsg["w"] = 80; - var req = new XMLHttpRequest(); - req.onerror = errHandler; - req.onreadystatechange = function () { - if (req.readyState != 4 || req.status != 200) - return; - var reply = JSON.parse(req.responseText); - if (reply.t == 's') { - /* Success */ - session.id = reply.id; - session.playing = true;
