shterm.js: Client-side message ordering

Make sure data from the server is written to the terminal emulator in
the correct order.  Out-of-order messages are stored in a queue until
their turn comes.
This commit is contained in:
John "Elwin" Edwards 2012-05-15 09:30:12 -07:00
parent 090e02ed59
commit c7995adad5

View file

@ -2,8 +2,9 @@
* is running a shell via the webtty.js server.
*/
/* The number of the next packet to send. */
var nsend = 0;
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.
// A state machine that keeps track of polling the server.
var ajaxstate = {
@ -116,6 +117,35 @@ function writeData(hexstr) {
return;
}
function processMsg(response) {
if (response.t != "d" || typeof(response.d) != "string")
return;
if (response.n === nrecv) {
writeData(response.d);
nrecv++;
var next;
/* msgQ must be shifted every time nrecv is incremented, but the process
* stops whenever an empty space, corresponding to an unarrived message,
* is encountered.
*/
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 " + response.n + ", expected " + nrecv);
msgQ[response.n - nrecv - 1] = response;
}
else {
/* This message's number was encountered previously. */
debug(1, "Discarding packet " + response.n + ", expected " + nrecv);
}
}
function getData() {
if (!termemu.alive)
return;
@ -134,8 +164,7 @@ function getData() {
else if (response.t == "n")
ajaxstate.gotnothing();
else if (response.t == "d") {
writeData(response.d);
debug(1, "Got packet " + response.n);
processMsg(response);
ajaxstate.gotdata();
}
return;
@ -162,8 +191,8 @@ function postResponseHandler() {
return;
/* It is a data message */
if (response.d) {
writeData(response.d);
debug(1, "Got packet " + response.n);
processMsg(response);
//debug(1, "Got packet " + response.n);
}
ajaxstate.posted();
return;
@ -316,6 +345,7 @@ function login(h, w) {
termemu.resize(logindict.h, logindict.w);
termemu.alive = true;
nsend = 0;
nrecv = 0;
setTitle("Logged in");
debug(1, "Logged in with id " + logindict.id);
getData();