Angular using Server Sent Events in a factory

前端 未结 2 1830
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-28 17:36

I am trying to setup message notifications in an Angular/Rails app.

When the user logs in, I want to open a SSE connection which will subscribe to a Redis stream and pu

2条回答
  •  故里飘歌
    2021-01-28 18:23

    Look into Oboe.js - http://oboejs.com/examples

    Using Oboe, I basically did (and I guess you don't need to inject $source and $http either in this case):

    .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);
            }
          };
        }
      ]);
    

    Then simply injected it and called from some controllers with:

    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){
            // ...
          });
    

    Very similar to other services that you'd see with $http, but instead you have a few more callbacks to consider.

    Oboe.js worked like a charm for me and the Golang go-json-rest package streaming a response (even with invalid JSON - which is quite common with streams since they aren't complete and won't have closing tags or will have extra commas, etc.). Just ensure the browser version of the script gets included on your page and you can just call it where ever. I spent a good while searching on how to do this with AngularJS, but there just didn't seem to be a straight forward facility for it. If it is at all possible.

    Of course from here you could probably figure out how to make it work for your needs...Update something in the $scope, etc.

提交回复
热议问题