I use nodejs with socket.io and angularjs on client. I picked up angular-socketio example from the Internet and added disconnect method to It.
Socket se
The core of the problem in this (just like in most of the other cases) is that the on method is called asynchronously most of the time (good!) but also synchronously in some cases (bad!).
When you call socket.disconnect() from your application (from within a controller which lives in the "angular context") it synchronously fires the disconnect event which then propagates into the on method which is designed to open the boundary into the angular context. But since you are already in the angular context, angular complains with the error you mentioned.
Since this issue is specific to the disconnect call the best options here are to
Example code:
angular.module('app')
.factory('socket', ['$rootScope', function ($rootScope, $timeout) {
var socket = io.connect();
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
disconnect: function () {
$timeout(socket.disconnect, 0, false);
},
socket: socket
};
}]);
or
angular.module('app')
.factory('socket', ['$rootScope', function ($rootScope) {
var socket = io.connect(),
disconnecting = false;
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
if (!disconnecting) {
$rootScope.$apply(function () {
callback.apply(socket, args);
});
} else {
callback.apply(socket, args);
}
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
disconnect: function () {
disconnecting = true;
socket.disconnect();
},
socket: socket
};
}]);