angular-socket-io icon indicating copy to clipboard operation
angular-socket-io copied to clipboard

What is the correct way to clean up (destroy) a socket

Open lrice opened this issue 10 years ago • 6 comments

I am trying to destroy the socket on $scope.$destroy, but I am still having sockets stack up when closing/opening a modal. I have tried socket.disconnect() but still see polling. I have been shutting the local socketio server to make sure that reconnect errors stop after the scope is destroyed but they continue and stack every time I re-open the modal.

What is the proper way to close/disconnect and dispose of sockets when leaving the modal/route where they were used?

lrice avatar Sep 10 '14 20:09 lrice

It is a little tricky with socket.io. Not sure what your needs are, but my app requires the socket to be torn down and thrown away on a logout, and a new one reconnected on a login. I've outlined how I do it in issue #86 along with a problem I have doing so with this library, and a workaround solution. Maybe it helps you?

davisford avatar Oct 26 '14 03:10 davisford

Definitely, given that I'm not making use of the forwarding or scope broadcast features, I may just wrap the socket myself or fork this repo rather than modifying the source though. Thanks for the info though, its definitely good to know why this was occurring.

lrice avatar Oct 27 '14 17:10 lrice

Can you clarify how you are calling disconnect?

Exposing the socket's disconnect method via my service seems to work fine for me:

.factory('Socket', (socketFactory)->

  ioSocket = io.connect('/', {})

  socketFactory = socketFactory({ioSocket: ioSocket})
  socketFactory.disconnect = ()->
    ioSocket.disconnect()

  return socketFactory
)

In some controller:

.controller('SomeController', (Socket)->
  $scope.disconnect =-> Socket.disconnect()
)

redders6600 avatar Oct 27 '14 19:10 redders6600

My factory looks something like this:

.factory('Socket', ['socketFactory', function(Socket){

    return function(){
      var socket = io.connect('<URL>', {forceNew: true});
      return Socket({ioSocket:socket});
    };

}]);

And when I disconnect, I have tried

.controller('somecontroller',['$scope','Socket',
  function ($scope,Socket){
    $scope.socket = Socket();
   ...

    $scope.on('$destroy', function(){
        $scope.socket.disconnect();
        and
        $scope.socket.disconnect(true);
    };
};

Is there a difference between ioSocket and the disconnect exposed by socketFactory? Have you tried the situation where there isn't a current connection to the server? That was the main issue for me, if I shut down the server while the connection was active, and THEN tried to disconnect, I could not prevent it from retrying infinitely (other than to put a cap on retry attempts, etc). I will try your method when I get a chance and see if that has an affect on my situation, but I was afraid that it was just a symptom of something like what @davisford was describing.

lrice avatar Oct 27 '14 20:10 lrice

@LukeRiceApperson I think I see your problem. You don't need to execute a fn/ctor on a dependency that is injected (like an angular service or factory). Angular already instantiates those for you.

So, I think your controller ought to instead be something like this:

.controller('somecontroller', ['$scope', 'Socket', function ($scope, Socket) {
    // isn't necessary to hang Socket off $scope unless you need to use it in an angular view expression
    $scope.socket = Socket;

    $scope.on('$destroy', function () {
      Socket.disconnect();
    });
}

That should work. There's another tip for debugging socket.io, run this in the console and then restart your app:

window.localStorage.debug = '*'; // that's an asterisk *

This will dump all kinds of debug info to the console on what socket.io / engine.io is doing.

davisford avatar Oct 28 '14 04:10 davisford

Is there a difference between ioSocket and the disconnect exposed by socketFactory?

Probably not - when I wrote that code this library wasn't exposing a disconnect method, so if it's implemented now it's likely the same.

I think @davisford has hit the nail on the head with regards to your problem.

redders6600 avatar Oct 28 '14 09:10 redders6600