Angular使用Server-sent-events(EventSource)接收数据,并在两个控制器之间处理它

Angular recive Data with Server-sent-events(EventSource) and handle it between 2 controllers

本文关键字:两个 控制器 之间 处理 EventSource Server-sent-events 使用 Angular 数据      更新时间:2023-09-26

这是我使用Angular.js的第一步。我谷歌了很多,但没有找到我问题的正确答案。

我的最终应用程序应该是这样的:没有用户交互。你浏览到网站,一切就开始了。页面等待服务器,服务器将发送服务器发送的事件到浏览器,将其显示在表中,并在一段时间后从表中选择第一个项目并处理它。

所以我认为这将是最好的2控制器和一个工厂。工厂连接到服务器并通过服务器发送的事件接收更新,将其放入数组中。这个数组被传递给第一个控制器,并显示在表中。第二个控制器也访问数组(或者使用函数返回(并删除)第一个元素)并处理它。

如果发现很多关于处理两个控制器之间的数据和更新视图的东西,当工厂中的数据发生变化。我还发现了一些关于服务器发送事件的例子。但它们都是在控制器中完成的,它们只是被转移到工厂,然后在控制器中使用。但我想建立一个中心点来保存数据并与服务器建立连接并从这个中心点更新控制器。这是错误的做法吗?

我应该在第一个控制器中建立连接并将数据推送到工厂中吗?只使用$rootScope?我不知道如何"正确"地处理我的问题。

我的代码到目前为止,是工厂连接到我的服务器和(据我所见)立即关闭连接,从未使用回调。当我使用Chrome访问localhost:3000/getStuff时,我收到了事件。现在我将代码更改为简单地查看控制台中的事件:
var module = angular.module('myApp',[]);

module.factory('DataService',function(){
var array=[];
var mesg;
var handleCallback = function (msg) {
    mesg = JSON.parse(msg.data);
    console.log(msg);
    console.log("callback");
}
var source = new EventSource('/getStuff');
source.addEventListener('message',handleCallback,false);
return {
    list: function () {
        return array;
    }
}
})

module.controller('MainCtrl',function($scope,DataService){
$scope.array = DataService.list;
})

我们已经用SSE用Angular构建了一个演示应用。你可以在GitHub上浏览它,并阅读相关的博客文章,以获得更多的上下文信息。基本上,这个应用程序使用APISpark和Google Sheets来构建测验,数据通过流数据检索。io,它依赖于SSE,发送实时和差异更新到UI,基于D3.JS。

我们已经创建了一个名为apiSparkStreamdataioFactory的工厂(在app.service.js中)来处理SSE通道(streamdataio)。createEventSource方法是一个包装器,它将收集所有所需的数据,而eventSource是在streamdata时创建的。方法调用)。当在SSE通道上接收数据时,我们使用$rootScope。$apply应用在每个视图中定义的回调,并处理接收到的数据。参见下面的代码:
 'use strict';
(function () {
  function apiSparkStreamdataioFactory(quizzConfig, $rootScope) {
    return {
      newStreamdata: function (url) {
        var headers = ['Authorization: Basic ' + btoa(quizzConfig.apiSparkLogin + ':' + quizzConfig.apiSparkPassword)];
        var streamdata = streamdataio.createEventSource(url, quizzConfig.streamdataioAppToken, headers);
        var data = [];
        function open() {
          streamdata.open();
          return this;
        }
        function onData(onDataCallback) {
          streamdata.onData(function (snapshot) {
            data = snapshot;
            $rootScope.$apply(function () {
              onDataCallback(data);
            });
          });
          return this;
        }
        function onPatch(onPatchCallback) {
          streamdata.onPatch(function (patches) {
            jsonpatch.apply(data, patches);
            $rootScope.$apply(function () {
              onPatchCallback(data);
            });
          });
          return this;
        }
        function close() {
          streamdata.close();
          return this;
        }
        function onError(onErrorCallback) {
          streamdata.onError(function (error) {
            onErrorCallback(error);
          });
          return this;
        }
        return {
          open: open,
          onData: onData,
          onPatch: onPatch,
          onError: onError,
          close: close
        };
      }
    }
  }
  angular
    .module('QuizzApp')
    .factory('apiSparkStreamdataioFactory', ['quizzConfig', '$rootScope', apiSparkStreamdataioFactory])
  ;

})();

希望这个示例能帮助您找到适合您的应用程序的解决方案。