带有服务器发送事件的 AngularJS

Posted

技术标签:

【中文标题】带有服务器发送事件的 AngularJS【英文标题】:AngularJS with Server-Sent Events 【发布时间】:2014-09-29 18:22:15 【问题描述】:

我有一个带有以下控制器的 AngularJS 应用程序。它与常规 JSON 资源上的 GET 和手动更新请求一起工作得很好,但我不能让它与服务器发送的事件一起工作。我面临的问题是,在我收到 SSE 事件并设置/更新 openListingsReport 变量后,我的视图没有得到更新。我显然错过了一个非常基本的概念。请帮我解决这个问题。

var rpCtrl = angular.module('rpCtrl', ['rpSvc']);

rpCtrl.controller('rpOpenListingsCtrl', ['$scope', 'rpOpenListingsSvc',
    function ($scope, rpOpenListingsSvc) 
        $scope.updating = false;

        if (typeof(EventSource) !== "undefined") 
            // Yes! Server-sent events support!
            var source = new EventSource('/listings/events');

            source.onmessage = function (event) 
                $scope.openListingsReport = event.data;
                $scope.$apply();
                console.log($scope.openListingsReport);
            ;
        
     else 
        // Sorry! No server-sent events support..
        alert('SSE not supported by browser.');
    

    $scope.update = function () 
        $scope.updateTime = Date.now();
        $scope.updating = true;
        rpOpenListingsSvc.update();
    

    $scope.reset = function () 
        $scope.updating = false;
    
]);

【问题讨论】:

EventSource 是否绑定到某种网络套接字(signalr 等)?您不能只将作用域函数放在角度控制器上,并期望服务器自动向它发送请求。 EventSource 是 html SSE 规范的一部分:developer.mozilla.org/en-US/docs/Web/API/EventSource 服务器不是问题。我在客户端 JS 中更新了 openListingsReport 的值。我只是无法让 AngularJS 在 HTML 中显示 openListingsReport 的更新值。 console.log($scope.openListingsReport) undefinednull 的输出是空白还是空白?尝试像这样附加消息事件:source.addEventListener('message', function(e) console.log(e.data); , false); 我发现这篇文章很有帮助:html5rocks.com/en/tutorials/eventsource/basics 我明白了,对不起。尝试将您的 $scope 声明放在 $apply() 中:$scope.$apply(function() $scope.openListingsReport = event.data;); 看看:smartjava.org/content/… 请注意,您很少需要调用$scope.$apply();脏检查应该可以处理绝大多数情况,包括这个 【参考方案1】:

问题出在下面一行:

$scope.openListingsReport = event.data;

应该是:

$scope.openListingsReport = JSON.parse(event.data);

【讨论】:

【参考方案2】:

只是一个建议,以防有人将 SSE 与 AngularJs 一起使用。

如果你想使用服务器端事件,我建议使用 AngularJS 内置的 $interval 服务,而不是 SSE。

以下是基本示例。

<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">

    <p>Randome no:</p>

    <h1>myWelcome</h1>

</div>

<p>The $interval service runs a function every specified millisecond.</p>

<script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function ($scope, $interval, $http) 
        $scope.myWelcome = new Date().toLocaleTimeString();
        $interval(function () 
            $scope.myWelcome = $http.get("test1.php").then(function (response) 
                $scope.myWelcome = response.data;
            );
        , 3000);
    );
</script>

</body>
</html>

test1.php

<?php

echo rand(0,100000);

【讨论】:

您的建议是轮询,对于许多应用程序而言,这远不如基于服务器的推送架构。 甚至每个人都已经知道,如果它可能有帮助,它只是一种替代方案。

以上是关于带有服务器发送事件的 AngularJS的主要内容,如果未能解决你的问题,请参考以下文章

使用带有nodejs的服务器发送事件并做出反应的问题

如何使用带有Rust的Actix Web和WebSockets发送服务器事件?

如何使用 _csrf 在 angularjs 中发送 POST 请求?

用于 angularjs 网站的带有 json rpc 的节点服务器

angularJs

在angularjs中发送带有%字符的json时出现格式错误的uri错误