Handle client reconnect properly

pull/3064/head
anugu-chegg 2018-02-10 22:30:22 +05:30 committed by muxator
parent 4265f4175e
commit bf05e9ae89
3 changed files with 131 additions and 6 deletions

View File

@ -1153,6 +1153,82 @@ function handleClientReady(client, message)
client.join(padIds.padId);
//Save the revision in sessioninfos, we take the revision from the info the client send to us
sessioninfos[client.id].rev = message.client_rev;
var changesetsNeeded = [];
var changesets = {};
var changesetsAuthor = {};
var changesetsTimestamp = {};
var startNum = message.client_rev + 1;
var endNum = pad.getHeadRevisionNumber() + 1;
async.series([
//fetch all changesets we need
function(callback)
{
var headNum = pad.getHeadRevisionNumber();
if (endNum > headNum+1)
endNum = headNum+1;
if (startNum < 0)
startNum = 0;
//create a array for all changesets, we will
//replace the values with the changeset later
for(var r=startNum;r<endNum;r++)
{
changesetsNeeded.push(r);
}
//get all changesets
async.forEach(changesetsNeeded, function(revNum)
{
pad.getRevisionChangeset(revNum, function(err, value)
{
if(ERR(err)) return;
changesets[revNum] = value;
});
pad.getRevisionAuthor(revNum, function(err, value)
{
if(ERR(err)) return;
changesetsAuthor[revNum] = value;
});
pad.getRevisionDate(revNum, function(err, value)
{
if(ERR(err)) return;
changesetsTimestamp[revNum] = value;
});
});
callback(null);
}
],
//return err and changeset
function(err)
{
if(ERR(err, callback)) return;
async.eachSeries(changesetsNeeded, function(r)
{
var forWire = Changeset.prepareForWire(changesets[r], pad.pool);
var wireMsg = {"type":"COLLABROOM",
"data":{type:"CLIENT_RECONNECT",
currRev: r,
newRev:pad.getHeadRevisionNumber(),
changeset:forWire.translated,
apool: forWire.pool,
author: changesetsAuthor[r],
currentTime: changesetsTimestamp[r]
}};
client.json.send(wireMsg);
});
if (startNum == endNum)
{
var Msg = {"type":"COLLABROOM",
"data":{type:"CLIENT_RECONNECT",
noChanges: true,
newRev:pad.getHeadRevisionNumber()
}};
console.log("About to send client reconnect event");
client.json.send(Msg);
}
});
}
//This is a normal first connect
else

View File

@ -60,6 +60,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
var debugMessages = [];
var msgQueue = [];
var socketIOError = false;
tellAceAboutHistoricalAuthors(serverVars.historicalAuthorData);
tellAceActiveAuthorInfo(initialUserInfo);
@ -181,7 +183,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
var sentMessage = false;
if (getSocket().realConnected) {
if (getSocket().realConnected && !socketIOError)
{
var userChangesData = editor.prepareUserChangeset();
if (userChangesData.changeset)
{
@ -198,9 +201,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
callbacks.onInternalAction("commitPerformed");
}
}
else {
// run again in a few seconds, to check if there was a reconnection attempt
setTimeout(wrapRecordingErrors("setTimeout(handleUserChanges)", handleUserChanges), 1000);
else
{
// run again in a few seconds, to detect a reconnect
setTimeout(wrapRecordingErrors("setTimeout(handleUserChanges)", handleUserChanges), 3000);
}
if (sentMessage)
@ -336,6 +340,44 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
});
handleUserChanges();
}
else if (msg.type == 'CLIENT_RECONNECT')
{
if (msg.noChanges)
{
socketIOError = false;
return;
}
var currRev = msg.currRev;
var newRev = msg.newRev;
var changeset = msg.changeset;
var author = (msg.author || '');
var apool = msg.apool;
if (rev + 1 == currRev)
{
if (author == pad.getUserId())
{
editor.applyPreparedChangesetToBase();
setStateIdle();
}
else
{
editor.applyChangesToBase(changeset, author, apool);
}
}
if (rev + 1 < currRev)
{
editor.applyChangesToBase(changeset, author, apool);
}
if (currRev == newRev)
{
socketIOError = false;
rev = newRev;
}
}
else if (msg.type == "NO_COMMIT_PENDING")
{
if (state == "COMMITTING")
@ -597,6 +639,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
schedulePerhapsCallIdleFuncs();
}
function setSocketIOError(value)
{
socketIOError = value;
}
function callWhenNotCommitting(func)
{
idleFuncs.push(func);
@ -663,7 +709,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
callWhenNotCommitting: callWhenNotCommitting,
addHistoricalAuthors: tellAceAboutHistoricalAuthors,
setChannelState: setChannelState,
setStateIdle: setStateIdle
setStateIdle: setStateIdle,
setSocketIOError: setSocketIOError
};
$(document).ready(setUpSocket);

View File

@ -209,11 +209,12 @@ function handshake()
socket.on('reconnect', function () {
socket.realConnected = true;
pad.collabClient.setChannelState("CONNECTED");
pad.sendClientReady(true);
pad.sendClientReady(receivedClientVars);
});
socket.on('reconnecting', function() {
socket.realConnected = false;
pad.collabClient.setStateIdle();
pad.collabClient.setChannelState("RECONNECTING");
});
@ -224,6 +225,7 @@ function handshake()
socket.on('error', function(error) {
socket.realConnected = false;
pad.collabClient.setStateIdle();
pad.collabClient.setSocketIOError(true);
});
var initalized = false;