'Angular-socket-io: how to disconnect the client

Update

Now the method socket.disconnect(close) has been included in angular-socket-io. It has a Boolean parameter 'close', if true, closes also the underlying connection.


I am using btford/angular-socket-io

What is the correct approach to disconnect the client?

I am trying to implement the following scenario

  1. user login --> connect to socket
  2. user logout --> disconnect from socket
  3. repeat (1) (2)

I succeeded to implement the connect (1) but I am having trouble with the disconnect (2)

This is what I tried: in my Authentication service I have the following

factory('AuthenticationService', function(socketFactory) {
  var mySocket;
  var service = {
      //...
      login: function(credentials) {
          var login = $http.post('/login', credentials);
          return login.then(function(response) {
            service.currentUser = response.data.user;
            if ( service.isAuthenticated() ) {
                // **connect to socket on login** 
                mySocket = socketFactory({ioSocket: io.connect('http://localhost')}); 
            }
            return service.isAuthenticated();
          });       
      },

      logout: function(redirectTo) {
          var logout = $http.get('/logout');
          logout.success(function() {
            service.currentUser = null;
            mySocket.disconnect();       // **disconnect on logout (not working)**
            redirect(redirectTo);
          });
          return logout;
      },
      //...
  };
  return service;
})

mySocket.disconnect();
gives the following error TypeError: Object # has no method 'disconnect'

mySocket.disconnect() works if instead of

mySocket = socketFactory({ioSocket: io.connect('http://localhost')});

I use

mySocket = io.connect('http://localhost'); 


Solution 1:[1]

The solution is very simple in fact :

Go edit the "socket.js" file from the Btford angular-socket module and you'll see :

var wrappedSocket = {

          on: addListener,

          addListener: addListener,



          emit: function (eventName, data, callback) {

            return socket.emit(eventName, data, asyncAngularify(socket, callback));

          },    


          removeListener: function () {

            return socket.removeListener.apply(socket, arguments);

          },



          // when socket.on('someEvent', fn (data) { ... }),

          // call scope.$broadcast('someEvent', data)

          forward: function (events, scope) {

            if (events instanceof Array === false) {

              events = [events];

            }

            if (!scope) {

              scope = defaultScope;

            }

            events.forEach(function (eventName) {

              var prefixedEvent = prefix + eventName;

              var forwardBroadcast = asyncAngularify(socket, function (data) {

                scope.$broadcast(prefixedEvent, data);

              });

              scope.$on('$destroy', function () {

                socket.removeListener(eventName, forwardBroadcast);

              });

              socket.on(eventName, forwardBroadcast);

            });

          }

        };

And then you just add this next to the others functions :

disconnect: function(){

                return socket.disconnect();

              },

And voilĂ , there you go :)

You should have something like that :

var wrappedSocket = {

          on: addListener,

          addListener: addListener,



          emit: function (eventName, data, callback) {

            return socket.emit(eventName, data, asyncAngularify(socket, callback));

          },



          disconnect: function(){

            return socket.disconnect();

          },



          removeListener: function () {

            return socket.removeListener.apply(socket, arguments);

          },



          // when socket.on('someEvent', fn (data) { ... }),

          // call scope.$broadcast('someEvent', data)

          forward: function (events, scope) {

            if (events instanceof Array === false) {

              events = [events];

            }

            if (!scope) {

              scope = defaultScope;

            }

            events.forEach(function (eventName) {

              var prefixedEvent = prefix + eventName;

              var forwardBroadcast = asyncAngularify(socket, function (data) {

                scope.$broadcast(prefixedEvent, data);

              });

              scope.$on('$destroy', function () {

                socket.removeListener(eventName, forwardBroadcast);

              });

              socket.on(eventName, forwardBroadcast);

            });

          }

        };

Solution 2:[2]

your code looks correct. I think the problem is variable hoisting, mySocket is hoisting. read here

Solution 3:[3]

My understanding is that btford/angular-socket-io wraps the socket instance in the socketFactory but does not expose a disconnet() method therefore it cannot be used to disconnect the socket from the client side.

Solution 4:[4]

Just call the RsocketClient.close() method .enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Damien Roelens
Solution 2 wayne
Solution 3 klode
Solution 4 justCurious