Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : socket.io destroy socket

I am working with a node socket.io server and an angular based socket.io client (using angular-socket.io), and it works well except in 1 specific condition: I cannot figure out how to totally destroy the socket when I am done with it when the socket was not able to connect.

The workflow is this: on a given page there is a button to open a modal, the opening of the modal injects the socket factory into the modals controller and a connection is made to the socket.io server. This all works well when the socket can connect. When the modal is closed, $scope.destroy is called and the handler in the modal controller attempts to clean up the socket.

This modal can be closed and reopened multiple times, or only once. My process of creating/destroying the socket multiple times may be part of my issue, this may not be the right paradigm, but when the modal is closed there will be no way to interact with it and after that page is left the socket certainly doesn't need to exist or remain connected.

Socket Creation:

angular.module('app.common.newSocketFactory', ['btford.socket-io'])
.factory('newSocketFactory', ['socketFactory', function(socketFactory){

 return function(){
   return socketFactory({ioSocket:io.connect('http://localhost:3000', {forceNew: true})});
 };

}]);

Injection:

angular.module('...', [
  'app.common.newSocketFactory',
  ....
])
.controller('Controller', ['$scope', '$modalInstance', 'newSocketFactory', ...
  function ($scope, $modalInstance, newSocketFactory, ...){
    ...

    $scope.socket = newSocketFactory();

Here is my destroy handler:

$scope.$on('$destroy', function(){
  $scope.socket.emit('unlisten');
  $scope.socket.disconnect();  //have tried passing true too.
});

This works correctly when the socket was able to connect before the modal was closed, the disconnected event in the server observes that the client disconnected. In addition, I can close the modal and THEN shut down the server and no attempt to reconnect occurs.

When the server is shut down when opening the modal, TransportErrors occur and reconnect attempts are made. If I close the modal at this point, the errors continue, and if I restart the server the retry is successful and the client will connect to the server. The worst part of this is I use this socket to maintain atomic access to a piece of hardware, which becomes locked by the first socket. Unless I restart the server, allow the socket to connect, and then close the modal (triggering $destroy on my isolate scope and socket.disconnect()), I have to refresh the entire page to destroy the socket.

This is potentially a angular-socket.io question or a regular socket.io client question. I asked on github in angular-socket.io with no response how to properly dispose of an angular-socket.io client socket with no response.

My question is this: A) If I am not making a major faux-pas with socket.io, how can I safely dispose of this client socket and B) If I am doing this wrong, what is a better way to go about managing a websocket that isn't supposed to persist from page to page.

Note: the angular-socket.io socket simply wraps the native socket with some stuff to help deal with angular scopes. When calling disconnect(), the result is what looks like the underlying socket itself. I have tried setting reconnect settings to false etc, but none of that has worked, and I don't like that the socket seems to still exist even after the scope is totally destroyed even if I CAN hack it to stop trying to connect.

Thanks

like image 266
Luke Rice Avatar asked Nov 10 '22 01:11

Luke Rice


1 Answers

When I dealt with similar issues I had the conclusion that SocketIO has a messy state management to say the least... So I'd try to create my own reconnection logic, e.g. disable reconnection on disconnect or error, and only reconnect if I want it to.

I'd also consider using native SocketIO with state handlers like (stuff) => $timeout(() => myHandler(stuff)) and putting a singleton angular service around it. This way your head won't ache about closing modals, lost scopes, etc.

Also please send your results, I'm pretty interested what you have experienced since then.

like image 64
Gábor Imre Avatar answered Nov 14 '22 23:11

Gábor Imre