Mercurial > hg > rlgwebd
changeset 14:155f3c104759
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.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Tue, 15 May 2012 09:30:12 -0700 |
parents | bf7c26d0b66d |
children | 7466927c17a5 |
files | shterm.js |
diffstat | 1 files changed, 36 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/shterm.js Sun May 13 20:50:13 2012 -0700 +++ b/shterm.js Tue May 15 09:30:12 2012 -0700 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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();