2014-04-30 2 views
2

AngularJs를 사용하여 WebSocket 연결을 처리하기 위해 factory을 작성했습니다. 그것은 controller 또는 factory/service 등의 각 코너 구성 요소가 메시지를 처리하기 위해 특정 콜백을 등록 할 수 있습니다 기본적으로AngularJs/다양한 컨트롤러에 WebSockets 이벤트/메시지 전달

.factory('WebSocketConnection', function() { 
     var service = {}; 
     service.callbacks = []; 
     service.connect = function() { 
      if(service.ws) 
       return; 
      var ws = new WebSocket("ws://localhost:9000/ws"); 
      ws.onmessage = function (message) { 
       angular.forEach(service.callbacks, function(callback){ 
        callback(message); 
       }); 
      }; 
      service.ws = ws; 
     }; 

     service.send = function(message) { 
      service.ws.send(message); 
     }; 

     service.subscribe = function(callback) { 
      service.callbacks.push(callback); 
     }; 
     return service; 
}); 

;
여기에 해당 코드의 그러므로 콜백 배열.
여기 청취 controller의 흥미로운 발췌입니다 :

WebSocketConnection.subscribe(function (message) { 
     $scope.$apply(function() { 
     var data = angular.fromJson(message.data); 
     $scope.notifications.push(data); 
     }); 
}); 

그래서 콜백 배열이 기능을 포함한다.

하지만 ... 내가이 컨트롤러를 더 이상 필요로하지 않는다면 어떨까요? (예를 들어 다른 컨트롤러를 기반으로 다른 페이지로 이동할 때)
콜백 항목 (이 함수)을 쓸모없는, 어쩌면 상충되는 프로세스를 피하기 위해 컨트롤러 사용을 할 때마다 배열에서 삭제해야합니다. 이후의 모든 메시지가 처리되는 한이 콜백. 특정 컨트롤러 그의 청취자/가입 자체를 관리 할 필요가 없도록
편리하지 ...

나는 공장에서 $rootScope에서 이벤트를 방송 할 수있는 방법에 대해 생각했다.
그러나 모든 범위 트리를 포함하고 싶지는 않습니다. 관련이없는 모든 범위를 포함합니다.

무엇이 좋은 습관입니까?

참고 : 1은 WebSocket 처리기 (출고시)이고 N은 병렬로 수신되는 각 구성 요소이며 메시지를 청취해야하는 관계를 1-N으로 설정해야합니다.

답변

1

@calebboyd에게 $scope 님의 destroy 이벤트의 존재를 상기시켜 주신 덕분에, 제 요구 사항을 달성하는 좋은 방법을 찾은 것 같습니다.

컨트롤러 탈퇴 자체가이 코드 조각을 추가하는 것입니다 수 있도록하기위한 반자동 방식 : 전체 공장 따라서

WebSocketConnection.subscribe($scope.$id, function (message) { //note the $scope.$id parameter 
     $scope.$apply(function() { 
     var data = angular.fromJson(message.data); 
     $scope.notifications.push(data); 
     }); 
}); 

: 메커니즘을 구독

$scope.$on("$destroy",function() { 
    WebSocketConnection.unsubscribe($scope.$id);  
}); 

는 다음과 같이 것을 코드는 다음과 같습니다 :

.factory('WebSocketConnection', function() { 
     var service = {}; 
     service.callbacks = {}; //note the object declaration, not Array 
     service.connect = function() { 
      if(service.ws) 
       return; 
      var ws = new WebSocket("ws://localhost:9000/ws"); 
      ws.onmessage = function (message) { 
       angular.forEach(service.callbacks, function(callback){ 
        callback(message); 
       }); 
      }; 
      service.ws = ws; 
     }; 

     service.send = function(message) { 
      service.ws.send(message); 
     }; 

     service.subscribe = function(concernedScopeId, callback) { 
      service.callbacks[concernedScopeId] = callback; 
     }; 

     service.unsubscribe = function(concernedScopeId) { 
      delete service.callbacks[concernedScopeId]; 
     }; 

     return service; 
}); 

그리고 그 트릭을 : 각 쓸모없는 콜백 ac 청취자로서의 청취는 검출되고 삭제 될 수있다.

+0

응용 프로그램에서 언제 소켓에 연결합니까? 언제 우리는 끊을 수 있습니까? – user3631341

1

서비스 또는 팩토리 개체에서 모델을 유지 관리하는 것이 좋습니다. 이렇게하면 메시지가 수신 될 때 응용 프로그램의 상태 (컨트롤러가있는 위치)에 의존하지 않고 데이터가 존재할 때 데이터와 상호 작용할 수 있습니다. 그것은 또한 당신의 개념을 적용 할 수 있습니다 할 수 있습니다

$ 범위를 모델 대신 $의 범위가 같은 것을 볼 수도

모델 등 :

ws.onmessage = function(event) { 
    $rootScope.$apply(function(){ 
     Service.notifications.push(event.data); 
    } 
} 

angular.module('MyApp').controller('MyCtrl', ['$scope', 'Service', 
function($scope, Service) { 
    $scope.notifications = Service.notifications; //references are === 
}]) 

유연성을 위해 메시지에 포함 된 데이터를 사용하여 업데이트해야 할 주 사용/방법을 결정한 다음 $injector을 사용할 수 있습니다.

+0

그러나 제시된 솔루션을 사용하면 '서비스'(정의로 인해 싱글 톤)가 전체 저장소로 작동합니다 (낭비되는 메모리는 무엇입니까?). 이벤트 위주의 솔루션은 "소비하거나 통과하지만 저장하지 않을 것입니다."보다는 "저장하면됩니다. 원할 경우 저에게 전화하십시오." 어떻게 생각해? – Mik378

+1

메모리가 걱정된다면'$ scope. $ on ("$ destroy", function() {$ scope.notifications.length = 0})과 같은 일을 할 수있다. ' 데이터가 사용/필요하지 않다면 제공된다. 아무데도 다른 곳 – calebboyd

+0

오'destroy'event의 존재를 잊어 버렸습니다. 기존 솔루션을 유지하고'$ scope. $ id'를 사용하여 콜백 배열에 대한 색인을 생성하면 어떨까요? 이렇게하면 해당 컨트롤러의'$ scope'가 파괴 될 때마다 올바른 콜백 아이템을 검색하고 삭제할 수 있습니다. 서명은 다음과 같이됩니다 :'service.subscribe = function (relevantScopeId, callback) {'. 그런 해결책으로, 나는 장소를 청소하기 전에 '다른 곳에 필요하지 않다'(당신이 쓴 것처럼) 통보를 가지고 다니지 않아도됩니다. 어떻게 생각해? (2 판;)) 감사합니다 – Mik378

관련 문제