【问题标题】:WebSocket callback not fired with angularjsWebSocket 回调未使用 angularjs 触发
【发布时间】:2017-04-18 13:30:58
【问题描述】:

我需要一个全局应用程序智能网络套接字,我的所有控制器都可以在应用程序中使用它。

以下代码描述了我创建工厂以共享单例 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)

【问题讨论】:

  • 您的 eventListener 是否应该读取“onmessage”?
  • 无法理解您的问题,是的,应该在 onmessage 上触发 eventListener
  • 尝试交换 emitsocket.on 并确保您的服务器正在发送任何数据
  • 我相信消息监听器不存在? onmessage 事件侦听器是套接字文档中记录的内容?
  • @Oskar 我确定服务器正在发送数据,检查代码我已经编辑了代码。

标签: javascript angularjs websocket


【解决方案1】:

摘要过程已经在进行中,您必须检查 $$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()

【讨论】:

  • 我们可以在工厂里有$scope 吗?
  • 理论上可以,但我不建议这样做,如果您在工厂中使用$rootScope,请考虑重构您的代码。 $$phase 可能也适用于 $rootScope
  • 它现在正在工作,但不明白如何,因为我的代码正在进入其他部分。还有更多为什么(!$scope.$$phase) 被认为是反模式?
  • @bruce_wayne 我认为它很容易出错,因为它可以创建竞争条件并触发许多不必要的$apply / $digest 一个接一个的阶段
  • 最好的方法是什么?
【解决方案2】:

您的socket.on() 事件正在运行与当前摘要周期冲突的摘要周期。

你可以使用setTimeut()来解决这个问题

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    相关资源
    最近更新 更多