Skip to content

Commit

Permalink
Add options.onPageRefresh = persist | close | none
Browse files Browse the repository at this point in the history
To replace recover: true
  • Loading branch information
SimonWoolf committed May 2, 2016
1 parent db4bcc1 commit 326e78d
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 10 deletions.
24 changes: 14 additions & 10 deletions common/lib/transport/connectionmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ var ConnectionManager = (function() {
params.connection_serial = this.connectionSerial;
break;
case 'recover':
if(options.recover === true) {
if(options.recover) {
var match = options.recover.match(/^(\w+):(\w+)$/);
if(match) {
params.recover = match[1];
params.connection_serial = match[2];
}
} else {
var connectionKey = readCookie(connectionKeyCookie),
connectionSerial = readCookie(connectionSerialCookie);
if(connectionKey !== null && connectionSerial !== null) {
params.recover = connectionKey;
params.connection_serial = connectionSerial;
}
} else {
var match = options.recover.match(/^(\w+):(\w+)$/);
if(match) {
params.recover = match[1];
params.connection_serial = match[2];
}
}
break;
default:
Expand Down Expand Up @@ -125,13 +125,17 @@ var ConnectionManager = (function() {
throw new Error(msg);
}

var self = this;

/* intercept close event in browser to persist connection id if requested */
if(createCookie && options.recover === true && window.addEventListener)
if(createCookie && options.onPageRefresh === 'persist' && window.addEventListener)
window.addEventListener('beforeunload', this.persistConnection.bind(this));

if(createCookie && options.onPageRefresh === 'close' && window.addEventListener)
window.addEventListener('beforeunload', function() { self.requestState({state: 'closing'}) });

/* Listen for online and offline events */
if(typeof window === "object" && window.addEventListener) {
var self = this;
window.addEventListener('online', function() {
if(self.state == self.states.disconnected || self.state == self.states.suspended) {
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager caught browser ‘online’ event', 'reattempting connection');
Expand Down Expand Up @@ -170,7 +174,7 @@ var ConnectionManager = (function() {
/* set up the transport params */
/* first attempt the main host; no need to check for general connectivity first.
* Inherit any connection state */
var mode = this.connectionKey ? 'resume' : (this.options.recover ? 'recover' : 'clean');
var mode = this.connectionKey ? 'resume' : ((this.options.onPageRefresh === 'persist') ? 'recover' : 'clean');
var transportParams = new TransportParams(this.options, null, mode, this.connectionKey, this.connectionSerial);
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.chooseTransport()', 'Transport recovery mode = ' + mode + (mode == 'clean' ? '' : '; connectionKey = ' + this.connectionKey + '; connectionSerial = ' + this.connectionSerial));
var self = this;
Expand Down
13 changes: 13 additions & 0 deletions common/lib/util/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ Defaults.normaliseOptions = function(options) {
options.queueMessages = options.queueEvents;
}

if(options.recover === true) {
Logger.deprecated('{recover: true}', '{onPageRefresh: "persist"}');
options.recover = undefined;
options.onPageRefresh = 'persist';
} else if(!('onPageRefresh' in options)) {
options.onPageRefresh = 'none';
} else if(options.onPageRefresh !== 'none' &&
options.onPageRefresh !== 'close' &&
options.onPageRefresh !== 'persist') {
Logger.logAction(Logger.LOG_ERROR, 'Defaults.normaliseOptions()', options.onPageRefresh.toString() + ' is an invalid value for options.onPageRefresh. Valid values are: "none", "close", or "persist".');
options.onPageRefresh = 'none';
}

if(!('queueMessages' in options))
options.queueMessages = true;

Expand Down
68 changes: 68 additions & 0 deletions spec/browser/connection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,74 @@ define(['ably', 'shared_helper'], function(Ably, helper) {
});
};

/* uses internal realtime knowledge of the format of the connection key to
* check if a connection key is the result of a successful recovery of another */
function sameConnection(keyA, keyB) {
return keyA.split("-")[0] === keyB.split("-")[0];
}

exports.page_refresh_with_onpagerefresh_persist = function(test) {
var realtime = helper.AblyRealtime({ onPageRefresh: 'persist' }),
refreshEvent = new Event('beforeunload', {'bubbles': true});

test.expect(2);
monitorConnection(test, realtime);

realtime.connection.once('connected', function() {
var connectionKey = realtime.connection.key;
document.dispatchEvent(refreshEvent);
test.equal(realtime.connection.state, 'connected', 'check connection state initially unaffected by page refresh');
simulateDroppedConnection(realtime);

var newRealtime = helper.AblyRealtime({ onPageRefresh: 'persist' });
newRealtime.connection.once('connected', function() {
test.ok(sameConnection(connectionKey, newRealtime.connection.key), 'Check new realtime recovered the connection from the cookie');
closeAndFinish(test, [realtime, newRealtime]);
});
});
};

exports.page_refresh_with_onpagerefresh_close = function(test) {
var realtime = helper.AblyRealtime({ onPageRefresh: 'close' }),
refreshEvent = new Event('beforeunload', {'bubbles': true});

test.expect(2);
monitorConnection(test, realtime);

realtime.connection.once('connected', function() {
var connectionKey = realtime.connection.key;
document.dispatchEvent(refreshEvent);
test.equal(realtime.connection.state, 'closing', 'check page refresh triggered a close');

var newRealtime = helper.AblyRealtime({ onPageRefresh: 'persist' });
newRealtime.connection.once('connected', function() {
test.ok(!sameConnection(connectionKey, newRealtime.connection.key), 'Check new realtime could not recover old even if it tries');
closeAndFinish(test, [realtime, newRealtime]);
});
});
};

exports.page_refresh_with_onpagerefresh_none = function(test) {
var realtime = helper.AblyRealtime({ onPageRefresh: 'none' }),
refreshEvent = new Event('beforeunload', {'bubbles': true});

test.expect(2);
monitorConnection(test, realtime);

realtime.connection.once('connected', function() {
var connectionKey = realtime.connection.key;
document.dispatchEvent(refreshEvent);
test.equal(realtime.connection.state, 'connected', 'check connection state initially unaffected by page refresh');
simulateDroppedConnection(realtime);

var newRealtime = helper.AblyRealtime({ onPageRefresh: 'persist' });
newRealtime.connection.once('connected', function() {
test.ok(!sameConnection(connectionKey, newRealtime.connection.key), 'Check new realtime could not recover old even if it tries');
closeAndFinish(test, [realtime, newRealtime]);
});
});
};

return module.exports = supportedBrowser() ? helper.withTimeout(exports) : {};

});

0 comments on commit 326e78d

Please sign in to comment.