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:
parent
090e02ed59
commit
c7995adad5
1 changed files with 36 additions and 6 deletions
42
shterm.js
42
shterm.js
|
|
@ -2,8 +2,9 @@
|
||||||
* is running a shell via the webtty.js server.
|
* is running a shell via the webtty.js server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The number of the next packet to send. */
|
var nsend = 0; // The number of the next packet to send.
|
||||||
var nsend = 0;
|
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.
|
// A state machine that keeps track of polling the server.
|
||||||
var ajaxstate = {
|
var ajaxstate = {
|
||||||
|
|
@ -116,6 +117,35 @@ function writeData(hexstr) {
|
||||||
return;
|
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() {
|
function getData() {
|
||||||
if (!termemu.alive)
|
if (!termemu.alive)
|
||||||
return;
|
return;
|
||||||
|
|
@ -134,8 +164,7 @@ function getData() {
|
||||||
else if (response.t == "n")
|
else if (response.t == "n")
|
||||||
ajaxstate.gotnothing();
|
ajaxstate.gotnothing();
|
||||||
else if (response.t == "d") {
|
else if (response.t == "d") {
|
||||||
writeData(response.d);
|
processMsg(response);
|
||||||
debug(1, "Got packet " + response.n);
|
|
||||||
ajaxstate.gotdata();
|
ajaxstate.gotdata();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -162,8 +191,8 @@ function postResponseHandler() {
|
||||||
return;
|
return;
|
||||||
/* It is a data message */
|
/* It is a data message */
|
||||||
if (response.d) {
|
if (response.d) {
|
||||||
writeData(response.d);
|
processMsg(response);
|
||||||
debug(1, "Got packet " + response.n);
|
//debug(1, "Got packet " + response.n);
|
||||||
}
|
}
|
||||||
ajaxstate.posted();
|
ajaxstate.posted();
|
||||||
return;
|
return;
|
||||||
|
|
@ -316,6 +345,7 @@ function login(h, w) {
|
||||||
termemu.resize(logindict.h, logindict.w);
|
termemu.resize(logindict.h, logindict.w);
|
||||||
termemu.alive = true;
|
termemu.alive = true;
|
||||||
nsend = 0;
|
nsend = 0;
|
||||||
|
nrecv = 0;
|
||||||
setTitle("Logged in");
|
setTitle("Logged in");
|
||||||
debug(1, "Logged in with id " + logindict.id);
|
debug(1, "Logged in with id " + logindict.id);
|
||||||
getData();
|
getData();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue