Created
March 2, 2016 21:28
-
-
Save jaredcnance/7211a19e9d116c1c2ce9 to your computer and use it in GitHub Desktop.
Ember Event Bus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// event-bus.js | |
// this is an EmberJS service, compatible and tested with Ember 2.3.1 | |
// manages the EventSource for the entire application | |
import Ember from 'ember'; | |
// TODO: add a method to remove a channel or handler from _openChannels | |
export default Ember.Service.extend({ | |
store: Ember.inject.service(), | |
_eventSource: null, | |
_openChannels: [{ | |
name: 'client.command', | |
handler: this.clientCommandHandler | |
}], | |
_keepAliveTimer: null, | |
_keepAliveTimeout: 120000, | |
// channels should be an array of name/handler objects: | |
// [ ... { name: 'channel-name', handler: function() {...} }, ...] | |
open(channels) { | |
let openChannels = this.get('_openChannels'); | |
let reOpenEventSource = false; | |
Ember.$(channels).each( | |
(i, channel) => { | |
// check if the channel is already subscribed to | |
let [openChannel] = $.grep(openChannels, function(openChannel) { | |
return openChannel.name === channel.name; | |
}); | |
if (openChannel) { // channel is already subscribed to | |
let oldHandler = openChannel.handler; | |
openChannel.handler = function() { | |
oldHandler(); | |
channel.handler(); // append the new handler | |
}; | |
} else { // channel is not subscribed to | |
reOpenEventSource = true; // need to close and re-open the event source to add the new channel | |
openChannels.push(channel); | |
} | |
} | |
); | |
this.set('_openChannels', openChannels); | |
if (reOpenEventSource) { | |
this.get('eventSourceReset').call(this); | |
} | |
}, | |
eventSourceReset() { | |
console.log('resetting event source'); | |
let adapter = this.get('store').adapterFor('application'); | |
let source = this.get('_eventSource'); | |
let openChannels = this.get('_openChannels'); | |
if (source) { | |
source.close(); | |
} | |
let channelNames = $.map(openChannels, | |
(channel) => { | |
return channel.name; | |
} | |
).join(','); | |
let streamUrl = `${adapter.buildURL('live-stream')}?channels=${channelNames}`; | |
this.get('startKeepAliveTimer').call(this); | |
source = new EventSource(streamUrl); | |
this.set('_eventSource', source); | |
source.addEventListener('message', (event) => { | |
this.channelMessageHandler.call(this, event); | |
}); | |
}, | |
channelMessageHandler(event) { | |
// reset the keep alive timer | |
this.get('cancelKeepAliveTimer').call(this); | |
this.get('startKeepAliveTimer').call(this); | |
// get the channel the message is coming in on and call the handler | |
let openChannels = this.get('_openChannels'); | |
let payload = JSON.parse(event.data); | |
let [channel] = $.grep(openChannels, function(channel) { | |
return channel.name === payload.channel; | |
}); | |
channel.handler(payload.channel, payload.message); | |
}, | |
startKeepAliveTimer() { | |
console.log('keep alive started'); | |
let _keepAliveTimeout = this.get('_keepAliveTimeout'); | |
let _keepAliveTimer = Ember.run.later(this, function() { | |
this.get('keepAliveHandler').call(this); | |
}, _keepAliveTimeout); | |
this.set('_keepAliveTimer', _keepAliveTimer); | |
}, | |
cancelKeepAliveTimer() { | |
console.log('keep alive cancelled'); | |
Ember.run.cancel(this.get('_keepAliveTimer')); | |
}, | |
keepAliveHandler() { | |
// kill the event source and open a new one | |
console.log('keep alive fired'); | |
let _eventSource = this.get('_eventSource'); | |
_eventSource.close(); | |
this.get('eventSourceReset').call(this); | |
}, | |
clientCommandHandler(channel, message) { | |
switch (message) { | |
case 'reload': | |
window.location.reload(true); | |
break; | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment