How to put server sent event (eventsource) into service?


#1

I want to have an ember service so that when new chat messages are avaliable it will be availabe to all the controllers.


#2

Hello

Something like?


// app/initializers/messages.js

export default {
  name: 'messages',
  initialize: initialize,
};

// consume sse endpoint
// https://github.com/segmentio/sse/blob/master/index.js

function subscribe(url, fn){
  var source = new EventSource(url);
  source.onmessage = function(e){
    fn(e.data);
  };
  source.onerror = function(e){
    if (source.readyState == EventSource.CLOSED) return;
    console.error(e);
  };
  return source.close.bind(source);
}

function initialize(application) {

  var messages = [];

  var unbind = subscribe('/updates', function(data){
    if (data == 'quit') unbind();
    messages.unshiftObject(data);
  });

  application.register('messages:main', messages, { instantiate: false });
  application.inject('controller', 'messages', 'messages:main'); .. make available to all controllers

}

// controllers/application.js

export default Em.Controller.extend({

  onNewMessage: Em.observer('messages.[]', function(){
   console.log(this.get('messages.firstObject'));
  });

});


#3

Thanks a lot , so we don’t need ember’s Services to do it ? https://guides.emberjs.com/v2.5.0/applications/services/


#4

@kelonye How can i use it in service?


#5

@v3ss0n tried something like:

// app/services/messages.js

export default Ember.Service.extend({

  content: [],

  init() {
    
    var self = this;
    self._super(...arguments);

    var unbind = subscribe('/updates', (data)=>{
      if (data == 'quit') unbind();
      self.get('content').unshiftObject(data);
    });
  },

});

// consume sse endpoint
// https://github.com/segmentio/sse/blob/master/index.js

function subscribe(url, fn){
  var source = new EventSource(url);
  source.onmessage = function(e){
    fn(e.data);
  };
  source.onerror = function(e){
    if (source.readyState == EventSource.CLOSED) return;
    console.error(e);
  };
  return source.close.bind(source);
}


// controllers/application.js

export default Em.Controller.extend({
  
  messages: Ember.inject.service('messages')

  onNewMessage: Em.observer('messages.content.[]', function(){
   console.log(this.get('messages.content.firstObject'));
  });

});


#6

thanks a lot, trying in a minute.

onNewMessage: observes the service’s content object? and init is started on Ember.inject.service(‘messages’) ?


#7

i tested and injected into controller but , it is not initing

need to call seperated init? @kelonye


#8

@kelonye it dosen’t initialize at all , need to call init() somwhere?