Mercurial > hg > rlgwebd
diff rlgterm.js @ 16:ef6127ed6da3
RLGWeb: switch to JSON protocol.
Port the JSON communication from WebTTY to RLGWeb. Fixing out-of-order
messages is still not implemented on the server side. Terminal size is
still hard-coded. Unused code is still lying around.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Thu, 17 May 2012 09:32:19 -0700 |
parents | 826a7ced69f8 |
children | 188bbd857124 |
line wrap: on
line diff
--- a/rlgterm.js Tue May 15 16:26:28 2012 -0700 +++ b/rlgterm.js Thu May 17 09:32:19 2012 -0700 @@ -111,33 +111,67 @@ 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. */ + * 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 msglines = msg.split("\n"); - var havedata = null; - if (!msglines[0]) + var msgDict; + var havedata = null; // eventual return value + try { + msgDict = JSON.parse(msg); + } catch (e) { + if (e instanceof SyntaxError) + return null; + } + if (!msgDict.t) return null; - if (msglines[0].charAt(0) == 'd') { - if (msglines[1]){ - writeData(msglines[1]); - havedata = true; + else if (msgDict.t == "E") { + if (msgDict.c == 1) { + logout(); + } + debug(1, "Server error: " + msgDict.s); + } + else if (msgDict.t == "n") { + havedata = false; + } + // A data message + else if (msgDict.t == "d"){ + if (msgDict.n === nrecv) { + writeData(msgDict.d); + nrecv++; + /* Process anything in the queue that's now ready. */ + var next; + while ((next = msgQ.shift()) !== undefined) { + writeData(next.d); + nrecv++; + } + } + else if (response.n > nrecv) { + /* The current message comes after one still missing. Queue this one + * for later use. */ + debug(1, "Got packet " + msgDict.n + ", expected " + nrecv); + msgQ[msgDict.n - nrecv - 1] = msgDict; } else { - havedata = false; + /* This message's number was encountered previously. */ + debug(1, "Discarding packet " + msgDict.n + ", expected " + nrecv); } + havedata = true; } - else if (msglines[0] == "E1") { - logout(); + else if (msgDict.t == "T") { + setTitle(msgDict.d); } - else if (msglines[0].charAt(0) == "T") { - setTitle(msglines[1]); - } - else if (msglines[0] == "q1") { + else if (msgDict.t == "q") { logout(); } else { - debug(1, "Unrecognized server message " + msglines[0]); + debug(1, "Unrecognized server message " + msg); } return havedata; } @@ -146,6 +180,7 @@ if (termemu.sessid == null) return; var datareq = new XMLHttpRequest(); + var msg = JSON.stringify({"id": termemu.sessid, "t": "n"}); datareq.onreadystatechange = function () { if (datareq.readyState == 4 && datareq.status == 200) { var wasdata = processMsg(datareq.responseText); @@ -159,7 +194,7 @@ } }; datareq.open('POST', '/feed', true); - datareq.send("id=" + termemu.sessid); + datareq.send(msg); return; } @@ -174,10 +209,11 @@ function sendback(str) { /* For responding to terminal queries. */ + var msgDict = {"id": termemu.sessid, "t": "d", "n": nsend++, "d": str}; var datareq = new XMLHttpRequest(); datareq.onreadystatechange = postResponseHandler; datareq.open('POST', '/feed', true); - datareq.send("id=" + termemu.sessid + "&keys=" + str); + datareq.send(JSON.stringify(msgDict)); return; } @@ -219,12 +255,14 @@ debug(1, "Ignoring keycode " + keynum); return; } + // Isn't this check redundant? if (termemu.sessid != null) ev.preventDefault(); var datareq = new XMLHttpRequest(); + var msgDict = {"id": termemu.sessid, "t": "d", "n": nsend++, "d": code}; datareq.onreadystatechange = postResponseHandler; datareq.open('POST', '/feed', true); - datareq.send("id=" + termemu.sessid + "&keys=" + code); + datareq.send(JSON.stringify(msgDict)); return; } @@ -270,11 +308,11 @@ } else return; - //writeData("Sending " + keystr); var datareq = new XMLHttpRequest(); + var msgDict = {"id": termemu.sessid, "t": "d", "n": nsend++, "d": keystr}; datareq.onreadystatechange = postResponseHandler; datareq.open('POST', '/feed', true); - datareq.send("id=" + termemu.sessid + "&keys=" + keystr); + datareq.send(JSON.stringify(msgDict)); return; } @@ -309,31 +347,34 @@ ev.preventDefault(); if (termemu.sessid != null) return; - var formname = document.getElementById("input_name").value; - var formpass = document.getElementById("input_pw").value; - var formgame = document.getElementById("input_game").value; - var formdata = "game=" + encodeURIComponent(formgame) + "&name=" + encodeURIComponent(formname) + "&pw=" + encodeURIComponent(formpass); + var loginmsg = {}; + loginmsg["name"] = document.getElementById("input_name").value; + loginmsg["pw"] = document.getElementById("input_pw").value; + loginmsg["game"] = document.getElementById("input_game").value; + loginmsg["h"] = 24; + loginmsg["w"] = 80; var req = new XMLHttpRequest(); req.onreadystatechange = function () { - if (req.readyState == 4 && req.status == 200) { - var datalines = req.responseText.split("\n"); - if (datalines[0] == 'l1') { - /* Success */ - termemu.sessid = datalines[1]; - setTitle("Playing as " + formname); - debug(1, "Logged in with id " + termemu.sessid); - document.getElementById("loginform").style.display = "none"; - getData(); - } - else { - debug(1, "Could not start game: " + datalines[1]); - document.getElementById("input_name").value = ""; - document.getElementById("input_pw").value = ""; - } + if (req.readyState != 4 || req.status != 200) + return; + var reply = JSON.parse(req.responseText); + if (reply.t == 'l') { + /* Success */ + termemu.sessid = reply.id; + termemu.resize(reply.h, reply.w); + setTitle("Playing as " + loginmsg["name"]); + debug(1, "Logged in with id " + termemu.sessid); + document.getElementById("loginform").style.display = "none"; + getData(); + } + else if (reply.t == 'E') { + debug(1, "Could not start game: " + reply.s); + document.getElementById("input_name").value = ""; + document.getElementById("input_pw").value = ""; } }; req.open('POST', '/login', true); - req.send(formdata); + req.send(JSON.stringify(loginmsg)); return; } @@ -342,6 +383,9 @@ return; termemu.sessid = null; setTitle("Game over."); + nsend = 0; + nrecv = 0; + msgQ = []; document.getElementById("loginform").style.display = "block"; return; } @@ -355,7 +399,7 @@ } }; req.open('POST', '/feed', true); - req.send("id=" + termemu.sessid + "&quit=quit"); + req.send(JSON.stringify({"id": termemu.sessid, "t": "q"})); return; }