Skip to content

Commit 6a6417c

Browse files
committed
Emit error if destroyed socket tries to connect
1 parent 7b49973 commit 6a6417c

File tree

2 files changed

+59
-17
lines changed

2 files changed

+59
-17
lines changed

lib/scsocket.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var clone = require('clone');
1212
var scErrors = require('sc-errors');
1313
var InvalidArgumentsError = scErrors.InvalidArgumentsError;
1414
var InvalidMessageError = scErrors.InvalidMessageError;
15+
var InvalidActionError = scErrors.InvalidActionError;
1516
var SocketProtocolError = scErrors.SocketProtocolError;
1617
var TimeoutError = scErrors.TimeoutError;
1718
var BadConnectionError = scErrors.BadConnectionError;
@@ -43,6 +44,7 @@ var SCSocket = function (opts) {
4344
// pingTimeout will be ackTimeout at the start, but it will
4445
// be updated with values provided by the 'connect' event
4546
this.pingTimeout = this.ackTimeout;
47+
this.active = true;
4648

4749
this._clientMap = opts.clientMap || {};
4850

@@ -144,10 +146,13 @@ var SCSocket = function (opts) {
144146
self.disconnect();
145147
};
146148

149+
if (isBrowser && this.disconnectOnUnload && global.addEventListener) {
150+
global.addEventListener('beforeunload', this._unloadHandler, false);
151+
}
152+
this._clientMap[this.clientId] = this;
153+
147154
if (this.options.autoConnect) {
148155
this.connect();
149-
} else {
150-
this.activate();
151156
}
152157
};
153158

@@ -254,7 +259,11 @@ SCSocket.prototype.deauthenticate = function (callback) {
254259
SCSocket.prototype.connect = SCSocket.prototype.open = function () {
255260
var self = this;
256261

257-
this.activate();
262+
if (!this.active) {
263+
var error = new InvalidActionError('Cannot connect a destroyed socket');
264+
this._onSCError(error);
265+
return;
266+
}
258267

259268
if (this.state == this.CLOSED) {
260269
this.pendingReconnect = false;
@@ -316,14 +325,6 @@ SCSocket.prototype.disconnect = function (code, data) {
316325
}
317326
};
318327

319-
SCSocket.prototype.activate = function () {
320-
if (isBrowser && this.disconnectOnUnload && global.addEventListener && !this.active) {
321-
global.addEventListener('beforeunload', this._unloadHandler, false);
322-
}
323-
this._clientMap[this.clientId] = this;
324-
this.active = true;
325-
};
326-
327328
SCSocket.prototype.destroy = function (code, data) {
328329
if (isBrowser && global.removeEventListener) {
329330
global.removeEventListener('beforeunload', this._unloadHandler, false);
@@ -433,7 +434,6 @@ SCSocket.prototype.authenticate = function (signedAuthToken, callback) {
433434
var self = this;
434435

435436
this.emit('#authenticate', signedAuthToken, function (err, authStatus) {
436-
437437
if (authStatus && authStatus.isAuthenticated != null) {
438438
// If authStatus is correctly formatted (has an isAuthenticated property),
439439
// then we will rehydrate the authError.
@@ -915,7 +915,6 @@ SCSocket.prototype._tryUnsubscribe = function (channel) {
915915
};
916916

917917
SCSocket.prototype.unsubscribe = function (channelName) {
918-
919918
var channel = this.channels[channelName];
920919

921920
if (channel) {

test/integration.js

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,30 +1026,73 @@ describe('integration tests', function () {
10261026
}, 1000);
10271027
});
10281028

1029-
it('should reactivate and reconnect socket if emit is called on a destroyed socket', function (done) {
1029+
it('should emit an error event if emit is called on a destroyed socket', function (done) {
10301030
client = socketClusterClient.create(clientOptions);
10311031
assert.equal(client.active, true);
10321032

1033+
var disconnectTriggered = false;
1034+
var secondConnectTriggered = false;
10331035
var clientError;
10341036
client.on('error', function (err) {
10351037
clientError = err;
10361038
});
10371039

10381040
client.once('connect', function () {
10391041
assert.equal(client.active, true);
1042+
1043+
client.once('disconnect', function () {
1044+
disconnectTriggered = true;
1045+
assert.equal(client.active, false);
1046+
});
1047+
10401048
client.destroy();
10411049
assert.equal(client.active, false);
10421050

10431051
client.once('connect', function () {
1044-
assert.equal(client.active, true);
1045-
done();
1052+
secondConnectTriggered = true;
10461053
});
10471054

10481055
client.emit('foo', 123);
10491056

1057+
assert.equal(client.active, false);
1058+
assert.equal(client.state, client.CLOSED);
1059+
});
1060+
1061+
setTimeout(function () {
1062+
assert.equal(secondConnectTriggered, false);
1063+
assert.equal(disconnectTriggered, true);
1064+
assert.notEqual(clientError, null);
1065+
assert.equal(clientError.name, 'InvalidActionError');
1066+
done();
1067+
}, 100);
1068+
});
1069+
1070+
it('should emit an error event if publish is called on a destroyed socket', function (done) {
1071+
client = socketClusterClient.create(clientOptions);
1072+
assert.equal(client.active, true);
1073+
1074+
var clientError;
1075+
client.on('error', function (err) {
1076+
clientError = err;
1077+
});
1078+
1079+
client.once('connect', function () {
10501080
assert.equal(client.active, true);
1051-
assert.equal(client.state, client.CONNECTING);
1081+
1082+
client.destroy();
1083+
assert.equal(client.active, false);
1084+
1085+
client.publish('thisIsATestChannel', 123);
1086+
1087+
assert.equal(client.active, false);
1088+
assert.equal(client.state, client.CLOSED);
10521089
});
1090+
1091+
setTimeout(function () {
1092+
assert.notEqual(clientError, null);
1093+
assert.equal(clientError.name, 'InvalidActionError');
1094+
done();
1095+
}, 100);
10531096
});
10541097

10551098
it('should correctly handle multiple successive connect and disconnect calls', function (done) {

0 commit comments

Comments
 (0)