1

I am using Socket.IO to pull data for plotting graphs, on var socket = io.connect(); my Node js server's io.on('connection', function(socket){}) starts a function, on interval of every 1 sec it emits the data to the clients connected.

I want the socket to close on change of Url (away from app) from client and server should stop emitting data.

Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
Ali
  • 427
  • 1
  • 4
  • 14
  • It will automatically close, you don't need to do anything. A *disconnect* event will trigger in the code. – Andrius Nov 20 '15 at 12:33
  • Are you talking about users actually navigating away from the page? In that case it will disconnect by itself. Or are you using `pushState()`? If so you can disconnect after listening to `window.onpopstate`. – Matt Harrison Nov 20 '15 at 12:37
  • Do you mean on a full navigation away from the Angular app or merely between different parts of an Angular SPA via its partial routing (via ng-router or ui-router)? – Eric McCormick Nov 20 '15 at 12:42
  • @EricMcCormick Yes I want to disconnect on change of angular route..and this is what I am using `$scope.$on('$destroy', function(){ socket.disconnect();});` – Ali Nov 20 '15 at 12:51
  • I think you'll need to attach that behavior similar to this: http://stackoverflow.com/questions/15445871/which-function-is-called-each-time-url-changes-in-angularjs/15445906#15445906 – Eric McCormick Nov 20 '15 at 12:54
  • 1
    Im currently away from a keyboard, I'll work up an example when I'm back at one. – Eric McCormick Nov 20 '15 at 13:02

2 Answers2

2

As we discussed in the comments to the question, you're looking to disconnect from the socket when your Angular ngRoute controller partial route changes away from a given state; this is different as a partial routing single-page application doesn't trigger a fully new page, but rather loads up partial content (defined in partial/template files or script definitions). This is key to why Furkan Başaran's answer won't work for you out of the box for changes between Angular routed states within the same SPA.

I've prepared a plunker that is a fairly basic AngularJS app; it has three html partials that it shows at three corresponding routes using ngRouter and invokes a function to <do-something> when the route change occurs. In this case, it's throwing an alert function, whereas in your case you may which to check for whether or not the route is to anything not the route you want to provide the socket functionality on.

Note: there is a change on every time the Angular app registers a route changes, so the initial establishment will register with a blank value for the / state, then every time it changes from the load, including the otherwise.redirectTo('/destination1').

Plunker (embedded) link: http://embed.plnkr.co/ayjgYCsox7RGl5OjyGsV/

Quick break down:

  1. I start by defining my handling function to be triggered on ngRouter changes. The passed value is the registered route (after the / or /index.html), such as /potatoes as is a case in my example. This is where you should perform your socket.disconnect();.
function changedMyPartialRoute(val){
    alert('url has changed to: ' + val);
}
  1. After I defined my app (angular.module('appName', [...), I define the config for my ngRouter setup.
.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
    $routeProvider
        .when('/meat', {
            templateUrl: 'meat.html',
            controller: 'MeatCtrl',
            controllerAs: 'meat'
        })
        .when('/potatoes', {
            templateUrl: 'potatoes.html',
            controller: 'PotatoCtrl',
            controllerAs: 'potato'
        })
        .when('/bacon', {
            templateUrl: 'bacon.html',
            controller: 'BaconCtrl',
            controllerAs: 'bacon'
        })
        .otherwise({
            redirectTo: '/meat'
        });
}])
  1. Finally, I invoke a run block on the app (module) to provide that hook into detecting the change. I'm passing in $rootScope and $location and it performs a $watch on the $rootScope to detect a change in the $location.path(). That whole run block:
.run( function($rootScope, $location) {
   $rootScope.$watch(function() { 
      return $location.path(); 
    },
    function(val){
      // the handling function from step 1
      changedMyPartialRoute(val);
    });
})

If you need to do something with $rootScope, as I suspect you might, you'll need to hand off the $rootScope handle through the changedMyPartialRoute function or just define your handling inline in the function callback in the .run block. This HTML5rocks.com tutorial shows their configuration in their Angular app by hooking into $rootScope, as opposed to $scope as you mentioned in the above comments.

I hope that helps!

Community
  • 1
  • 1
Eric McCormick
  • 2,716
  • 2
  • 19
  • 37
0

When client closed connection close automatically, if you want see this, write this code to your node server and look to console when closed your client tab.

io.on('disconnect', function() {
   console.log("Connection disconnected");
})
Furkan Başaran
  • 1,927
  • 2
  • 19
  • 28