簡體   English   中英

Angular在工廠中使用服務器發送事件

[英]Angular using Server Sent Events in a factory

我正在嘗試在Angular / Rails應用程序中設置消息通知。

當用戶登錄時,我想打開一個SSE連接,該連接將訂閱Redis流,並在用戶收到新消息時向客戶端推送警報。

我已經完成SSE的設置並可以正常工作,但是無法找到一種方法來在用戶注銷時可靠地關閉SSE連接。 我試圖建立一個服務來處理SSE的打開和關閉:

angular.module('messagesApp')
.factory('StreamHandler', function(CookieHandler, MessageStream){
  var StreamHandler = {

    set: function(){
      var user
      user = CookieHandler.get();
      MessageStream.get = function(){
        var source = new EventSource('/api/v1/messages/count?id='+user.id)
        return source
      }
    },

    get: function(){
      var source = MessageStream.get()
      source.onmessage = function(event) {
        //do something
      }
    },

    kill: function(){
      var source = MessageStream.get()
      source.close()
    }
  }

  return StreamHandler
})

我無法弄清楚如何殺死在StreamHandler.set()打開的流。 我在kill屬性中的嘗試不起作用,可能是因為調用getter實際上會創建一個新流嗎?

我對其他方法持開放態度:我只需要一種在用戶登錄/注銷時設置和EventSource流的方法。

問題是我將創建EventSource的函數放在get屬性中,而不是實際的EventSource對象。 進行一些更改即可使其工作:

.factory('StreamHandler', function(CookieHandler, MessageStream){
  var StreamHandler = {

    set: function(){
      var user
      user = CookieHandler.get();
      var source = new EventSource('/api/v1/messages/count?id='+user.id)
      MessageStream.get = source
    },

    get: function(){
      var source = MessageStream.get
      source.onmessage = function(event) {
        console.log(event)
      }
      source.onerror = function(error) {
        source.close()
      }
    },

    kill: function(){
      var source = MessageStream.get
      source.close();

    }
  }

  return StreamHandler
})

查看Oboe.js- http: //oboejs.com/examples

使用Oboe,我基本上做到了(我猜您在這種情況下也不需要注入$ source和$ http):

.factory('MyStreamingResource', ['$resource', '$http', 
    function($resource, $http) {
      return {
        stream: function(options, startFn, nodeFn, doneFn) {
          oboe('//url/' + 'maybeSomeOptions/?maybe=' + options.passedAbove)
           .start(startFn)
           .node(options.path, nodeFn)
           .done(doneFn);
        }
      };
    }
  ]);

然后簡單地注入它,並從一些控制器中調用:

MyStreamingResource.stream({
        passedAbove: 'foo',
        path: 'items.*'
      },
      // start callback
      function(status, headers){
        // console.dir(headers);
        // this.abort(); // could be called from here too
      },
      // node callback (where your data is going to be streamed to)
      function(data){
        if(data !== null) {
          console.dir(data);
          //this.abort();
        }
      },
      // done (if you really want to wait)
      function(parsedJson){
        // ...
      });

與$ http會看到的其他服務非常相似,但是您需要考慮其他一些回調。

Oboe.js對我來說就像一個魅力,Golang的go-json-rest包流了一個響應(即使使用無效的JSON-這在流中很常見,因為它們不完整並且沒有結束標簽,或者會有額外的逗號等)。 只要確保腳本的瀏覽器版本包含在頁面中,就可以在任何地方調用它。 我花了很多時間研究如何使用AngularJS進行此操作,但似乎並沒有直接的工具。 如果有可能的話。

當然,您可以從這里開始弄清楚如何使其滿足您的需求...更新$ scope中的內容,等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM