2017-04-18 67 views
1

我需要一個全球性的應用程序明智的網絡套接字,它可以被我的所有控制器在應用程序中使用。WebSocket回調未觸發angularjs

以下代碼描述了我創建工廠以共享單例websocket對象的用例。提供的接口允許控制器通過套接字發送數據並附加偵聽器以接收消息。

以下代碼的問題是,我能夠按照預期發送套接字上的數據,但無法在套接字上發送數據。

我已經閱讀了幾個角度摘要相關的解決方案,但它們不適合我。

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));

,而不是

socket.addEventListener('message', callback);

引發以下錯誤

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

+0

如果你的事件監聽是閱讀 '的onMessage'? – Jackthomson

+0

無法理解你的問題,是的eventListener應該被解僱onmessage –

+0

嘗試交換'emit'和'socket.on'並確保你的服務器正在發送任何數據 – Oskar

回答

2

摘要過程已經在進行中,你必須檢查$$phase,敷用if語句代碼:

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

詳細檢查:AngularJS : Prevent error $digest already in progress when calling $scope.$apply()

+0

我們可以在工廠內有$ scope嗎? –

+0

理論上你可以,但我不會建議,如果你在你的工廠中使用'$ rootScope',考慮重構你的代碼。 '$$ phase''可能與'$ rootScope'一起工作 – Oskar

+0

它現在正在工作,並且不知道如何,因爲我的代碼進入了其他部分。還有更多的事情爲什麼'(!$ scope。$$ phase)'被認爲是反模式? –

0

socket.on()活動的持續消化週期,這與目前的消化週期衝突。

可以使用setTimeut()來解決這個問題

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