2017-04-18 7 views
1

Ich brauche eine globale Anwendung weise Web-Socket, die von allen meiner Controller in App verwendet werden kann.WebSocket-Callback nicht mit angularjs gefeuert

Der folgende Code beschreibt die meine Anwendungsfall, wo ich eine Fabrik bin die Schaffung eines Singletons websocket Objekt zu teilen. Mit der bereitgestellten Schnittstelle können die Controller die Daten über den Socket senden und den Listener für eingehende Nachrichten anhängen.

Das Problem mit dem folgenden Code ist, dass ich in der Lage bin, die Daten auf dem Sockel zu senden, wie erwartet, aber nicht in der Lage, Daten zu empfangen, wenn es über die Steckdose kommt.

Ich habe mehrere eckige Digest bezogene Lösungen gelesen, aber sie funktionieren nicht für mich.

angular 
    .module('myApp', []) 
    .factory('socket', function() { 
    var socketStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']; 
    var socket = new WebSocket("ws://localhost:7070/ws"); 
    socket.onopen = function(event) { 
     socket.send("hello"); 
    }; 

    socket.addEventListener('message', function(event) { 
     // I am able to see this so, it is confirmed that server is sending the data 
     console.log(event); 
    }); 

    return { 
     emit: function (data) { 
     socket.send(JSON.stringify(data)); 
     }, 
     on: function(callback) { 
     socket.addEventListener('message', callback); 
     }, 
     getStatus: function() { 
     var status = socket.readyState; 
     return socketStates[status] 
     } 
    }; 
    }) 
    .controller('MyController', function(socket){ 
    var myctl = this; 

    //This works 
    socket.emit({type : "register", name: producer}); 

    //This doesn't work 
    socket.on(function(event) { 
     console.log(event); 
    }); 
    }); 

$rootScope.$apply(socket.addEventListener('message', callback));

statt

socket.addEventListener('message', callback);

führt den folgenden Fehler

vendor.js:5 Error: [$rootScope:inprog] $digest already in progress(…)(anonymous function)

+0

Sollte sein zu lösen 'onmessage' zu lesen? – Jackthomson

+0

konnte Ihre Frage nicht verstehen, ja die eventlistener sollte auf onmessage –

+0

abgefeuert werden versuchen 'emit' und' socket.on' Swapping und sicherzustellen, dass der Server keine Daten sendet – Oskar

Antwort

2

Der Digest Prozess ist bereits im Gange Sie die 0 überprüfenund wickeln Sie Ihren Code mit if-Anweisung:

if (!$scope.$$phase) { 
    $rootScope.$apply(socket.addEventListener('message', callback)); 
} else { 
    socket.addEventListener('message', callback); 
} 

Weitere Check: AngularJS : Prevent error $digest already in progress when calling $scope.$apply()

+0

können wir '$ scope' in der Fabrik haben? –

+0

In der Theorie können Sie, aber ich würde nicht empfehlen, dass, wenn Sie '$ rootScope' in Ihrer Fabrik verwenden, erwägen Sie, Ihren Code zu refactoring. '$$ phase' funktioniert wahrscheinlich mit' $ rootScope' sowie – Oskar

+0

Es funktioniert jetzt, und ich verstehe nicht wie, weil mein Code in noch anderen Teil geht. Und noch etwas, warum '(! $ Scope. $$ phase)' als Anti-Pattern betrachtet wird? –

0

Ihr socket.on() Ereignis Laufzyklus verdauen, die mit Strom verdauen Zyklus Konflikt ist.

können Sie setTimeut() verwenden dieses Problem Ihre eventlistener

setTimeout(function(){ 
     socket.on(function(event) { 
      console.log(event); 
     }); 
}); 
Verwandte Themen