You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.5 KiB

4 years ago
  1. 'use strict';
  2. var inherits = require('inherits')
  3. , EventEmitter = require('events').EventEmitter
  4. , EventSourceDriver = require('eventsource')
  5. ;
  6. var debug = function() {};
  7. if (process.env.NODE_ENV !== 'production') {
  8. debug = require('debug')('sockjs-client:receiver:eventsource');
  9. }
  10. function EventSourceReceiver(url) {
  11. debug(url);
  12. EventEmitter.call(this);
  13. var self = this;
  14. var es = this.es = new EventSourceDriver(url);
  15. es.onmessage = function(e) {
  16. debug('message', e.data);
  17. self.emit('message', decodeURI(e.data));
  18. };
  19. es.onerror = function(e) {
  20. debug('error', es.readyState, e);
  21. // ES on reconnection has readyState = 0 or 1.
  22. // on network error it's CLOSED = 2
  23. var reason = (es.readyState !== 2 ? 'network' : 'permanent');
  24. self._cleanup();
  25. self._close(reason);
  26. };
  27. }
  28. inherits(EventSourceReceiver, EventEmitter);
  29. EventSourceReceiver.prototype.abort = function() {
  30. debug('abort');
  31. this._cleanup();
  32. this._close('user');
  33. };
  34. EventSourceReceiver.prototype._cleanup = function() {
  35. debug('cleanup');
  36. var es = this.es;
  37. if (es) {
  38. es.onmessage = es.onerror = null;
  39. es.close();
  40. this.es = null;
  41. }
  42. };
  43. EventSourceReceiver.prototype._close = function(reason) {
  44. debug('close', reason);
  45. var self = this;
  46. // Safari and chrome < 15 crash if we close window before
  47. // waiting for ES cleanup. See:
  48. // https://code.google.com/p/chromium/issues/detail?id=89155
  49. setTimeout(function() {
  50. self.emit('close', null, reason);
  51. self.removeAllListeners();
  52. }, 200);
  53. };
  54. module.exports = EventSourceReceiver;