Do a reconnect on network problems. After 10s it gives up

pull/239/merge
Peter 'Pita' Martischka 2011-11-25 15:24:10 -08:00
parent 53bf7dc19d
commit fa098d73cd
5 changed files with 80 additions and 203 deletions

View File

@ -806,8 +806,20 @@ function handleClientReady(client, message)
clientVars.userName = authorName;
}
//Send the clientVars to the Client
client.json.send(clientVars);
//This is a reconnect, so we don't have to send the client the ClientVars again
if(message.reconnect == true)
{
//Save the revision in sessioninfos, we take the revision from the info the client send to us
sessioninfos[client.id].rev = message.client_rev;
}
//This is a normal first connect
else
{
//Send the clientVars to the Client
client.json.send(clientVars);
//Save the revision in sessioninfos
sessioninfos[client.id].rev = pad.getHeadRevisionNumber();
}
//Save the revision and the author id in sessioninfos
sessioninfos[client.id].rev = pad.getHeadRevisionNumber();

View File

@ -469,7 +469,7 @@ table#otheruserstable { display: none; }
.modaldialog.cboxreconnecting .modaldialog-inner,
.modaldialog.cboxconnecting .modaldialog-inner {
background: url(static/img/connectingbar.gif) no-repeat center 60px;
background: url(../../static/img/connectingbar.gif) no-repeat center 60px;
height: 100px;
}
.modaldialog.cboxreconnecting {

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -77,10 +77,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
{
if (socket)
{
/*socket.onclosed = function() {};
socket.onhiccup = function() {};
socket.disconnect(true);*/
socket.disconnect();
setChannelState("DISCONNECTED", "unload");
}
});
if ($.browser.mozilla)
@ -100,18 +97,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
editor.setBaseAttributedText(serverVars.initialAttributedText, serverVars.apool);
editor.setUserChangeNotificationCallback(wrapRecordingErrors("handleUserChanges", handleUserChanges));
function abandonConnection(reason)
{
if (socket)
{
/*socket.onclosed = function() {};
socket.onhiccup = function() {};*/
socket.disconnect();
}
socket = null;
setChannelState("DISCONNECTED", reason);
}
function dmesg(str)
{
if (typeof window.ajlog == "string") window.ajlog += str + '\n';
@ -124,7 +109,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
{
if (channelState == "CONNECTING" && (((+new Date()) - initialStartConnectTime) > 20000))
{
abandonConnection("initsocketfail"); // give up
setChannelState("DISCONNECTED", "initsocketfail");
}
else
{
@ -141,8 +126,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
if (state == "COMMITTING" && (t - lastCommitTime) > 20000)
{
// a commit is taking too long
appLevelDisconnectReason = "slowcommit";
socket.disconnect();
setChannelState("DISCONNECTED", "slowcommit");
}
else if (state == "COMMITTING" && (t - lastCommitTime) > 5000)
{
@ -230,11 +214,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
handleMessageFromServer(obj);
});*/
socket.on('disconnect', function(obj)
{
handleSocketClosed(true);
});
/*var success = false;
callCatchingErrors("setUpSocket", function() {
appLevelDisconnectReason = null;
@ -366,7 +345,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
if (newRev != (rev + 1))
{
dmesg("bad message revision on NEW_CHANGES: " + newRev + " not " + (rev + 1));
socket.disconnect();
setChannelState("DISCONNECTED", "badmessage_newchanges");
return;
}
rev = newRev;
@ -378,7 +357,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
if (newRev != (rev + 1))
{
dmesg("bad message revision on ACCEPT_COMMIT: " + newRev + " not " + (rev + 1));
socket.disconnect();
setChannelState("DISCONNECTED", "badmessage_acceptcommit");
return;
}
rev = newRev;
@ -520,48 +499,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
//pad.dmesg($.map(getConnectedUsers(), function(u) { return u.userId.slice(-2); }).join(','));
}
function handleSocketClosed(params)
{
socket = null;
$.each(keys(userSet), function()
{
var uid = String(this);
if (uid != userId)
{
var userInfo = userSet[uid];
delete userSet[uid];
callbacks.onUserLeave(userInfo);
dmesgUsers();
}
});
var reason = appLevelDisconnectReason || params.reason;
var shouldReconnect = params.reconnect;
if (shouldReconnect)
{
// determine if this is a tight reconnect loop due to weird connectivity problems
reconnectTimes.push(+new Date());
var TOO_MANY_RECONNECTS = 8;
var TOO_SHORT_A_TIME_MS = 10000;
if (reconnectTimes.length >= TOO_MANY_RECONNECTS && ((+new Date()) - reconnectTimes[reconnectTimes.length - TOO_MANY_RECONNECTS]) < TOO_SHORT_A_TIME_MS)
{
setChannelState("DISCONNECTED", "looping");
}
else
{
setChannelState("RECONNECTING", reason);
setUpSocket();
}
}
else
{
setChannelState("DISCONNECTED", reason);
}
}
function setChannelState(newChannelState, moreInfo)
{
if (newChannelState != channelState)
@ -650,128 +587,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
return rev;
}
function getDiagnosticInfo()
{
var maxCaughtErrors = 3;
var maxAceErrors = 3;
var maxDebugMessages = 50;
var longStringCutoff = 500;
function trunc(str)
{
return String(str).substring(0, longStringCutoff);
}
var info = {
errors: {
length: 0
}
};
function addError(e, catcher, time)
{
var error = {
catcher: catcher
};
if (time) error.time = time;
// a little over-cautious?
try
{
if (e.description) error.description = e.description;
}
catch (x)
{}
try
{
if (e.fileName) error.fileName = e.fileName;
}
catch (x)
{}
try
{
if (e.lineNumber) error.lineNumber = e.lineNumber;
}
catch (x)
{}
try
{
if (e.message) error.message = e.message;
}
catch (x)
{}
try
{
if (e.name) error.name = e.name;
}
catch (x)
{}
try
{
if (e.number) error.number = e.number;
}
catch (x)
{}
try
{
if (e.stack) error.stack = trunc(e.stack);
}
catch (x)
{}
info.errors[info.errors.length] = error;
info.errors.length++;
}
for (var i = 0;
((i < caughtErrors.length) && (i < maxCaughtErrors)); i++)
{
addError(caughtErrors[i], caughtErrorCatchers[i], caughtErrorTimes[i]);
}
if (editor)
{
var aceErrors = editor.getUnhandledErrors();
for (var i = 0;
((i < aceErrors.length) && (i < maxAceErrors)); i++)
{
var errorRecord = aceErrors[i];
addError(errorRecord.error, "ACE", errorRecord.time);
}
}
info.time = +new Date();
info.collabState = state;
info.channelState = channelState;
info.lastCommitTime = lastCommitTime;
info.numSocketReconnects = reconnectTimes.length;
info.userId = userId;
info.currentRev = rev;
info.participants = (function()
{
var pp = [];
for (var u in userSet)
{
pp.push(u);
}
return pp.join(',');
})();
if (debugMessages.length > maxDebugMessages)
{
debugMessages = debugMessages.slice(debugMessages.length - maxDebugMessages, debugMessages.length);
}
info.debugMessages = {
length: 0
};
for (var i = 0; i < debugMessages.length; i++)
{
info.debugMessages[i] = trunc(debugMessages[i]);
info.debugMessages.length++;
}
return info;
}
function getMissedChanges()
{
var obj = {};
@ -863,10 +678,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options)
sendClientMessage: sendClientMessage,
sendMessage: sendMessage,
getCurrentRevisionNumber: getCurrentRevisionNumber,
getDiagnosticInfo: getDiagnosticInfo,
getMissedChanges: getMissedChanges,
callWhenNotCommitting: callWhenNotCommitting,
addHistoricalAuthors: tellAceAboutHistoricalAuthors
addHistoricalAuthors: tellAceAboutHistoricalAuthors,
setChannelState: setChannelState
});
}

View File

@ -167,15 +167,17 @@ function handshake()
var resource = loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "socket.io";
//connect
socket = io.connect(url, {
resource: resource
resource: resource,
'max reconnection attempts': 3
});
socket.once('connect', function()
function sendClientReady(isReconnect)
{
var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1);
padId = unescape(padId); // unescape neccesary due to Safari and Opera interpretation of spaces
document.title = document.title + " | " + padId;
if(!isReconnect)
document.title = document.title + " | " + padId;
var token = readCookie("token");
if (token == null)
@ -196,7 +198,43 @@ function handshake()
"token": token,
"protocolVersion": 2
};
//this is a reconnect, lets tell the server our revisionnumber
if(isReconnect == true)
{
msg.client_rev=pad.collabClient.getCurrentRevisionNumber();
msg.reconnect=true;
}
socket.json.send(msg);
};
var disconnectTimeout;
socket.once('connect', function () {
sendClientReady(false);
});
socket.on('reconnect', function () {
//reconnect is before the timeout, lets stop the timeout
if(disconnectTimeout)
{
clearTimeout(disconnectTimeout);
}
pad.collabClient.setChannelState("CONNECTED");
sendClientReady(true);
});
socket.on('disconnect', function () {
function disconnectEvent()
{
pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout");
}
pad.collabClient.setChannelState("RECONNECTING");
disconnectTimeout = setTimeout(disconnectEvent, 10000);
});
var receivedClientVars = false;
@ -352,7 +390,6 @@ var pad = {
//initialize the chat
chat.init();
pad.diagnosticInfo.uniqueId = padutils.uniqueId();
pad.initTime = +(new Date());
pad.padOptions = clientVars.initialOptions;
@ -649,7 +686,22 @@ var pad = {
else if (newState == "DISCONNECTED")
{
pad.diagnosticInfo.disconnectedMessage = message;
pad.diagnosticInfo.padInitTime = pad.initTime;
pad.diagnosticInfo.padId = pad.getPadId();
pad.diagnosticInfo.socket = {};
//we filter non objects from the socket object and put them in the diagnosticInfo
//this ensures we have no cyclic data - this allows us to stringify the data
for(var i in socket.socket)
{
var value = socket.socket[i];
var type = typeof value;
if(type == "string" || type == "number")
{
pad.diagnosticInfo.socket[i] = value;
}
}
pad.asyncSendDiagnosticInfo();
if (typeof window.ajlog == "string")
{
@ -721,7 +773,6 @@ var pad = {
},
asyncSendDiagnosticInfo: function()
{
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
window.setTimeout(function()
{
$.ajax(
@ -729,7 +780,6 @@ var pad = {
type: 'post',
url: '/ep/pad/connection-diagnostic-info',
data: {
padId: pad.getPadId(),
diagnosticInfo: JSON.stringify(pad.diagnosticInfo)
},
success: function()
@ -809,7 +859,7 @@ var pad = {
},
preloadImages: function()
{
var images = []; // Removed as we now use CSS and JS for colorpicker
var images = ["../static/img/connectingbar.gif"];
function loadNextImage()
{