a zip code crypto-currency system good for red ONLY

base.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. 'use strict';
  2. var Emitter = require('events').EventEmitter,
  3. util = require('util'),
  4. streams = require('../streams'),
  5. Headers = require('./headers'),
  6. Reader = require('./stream_reader');
  7. var Base = function(request, url, options) {
  8. Emitter.call(this);
  9. Base.validateOptions(options || {}, ['maxLength', 'masking', 'requireMasking', 'protocols']);
  10. this._request = request;
  11. this._reader = new Reader();
  12. this._options = options || {};
  13. this._maxLength = this._options.maxLength || this.MAX_LENGTH;
  14. this._headers = new Headers();
  15. this.__queue = [];
  16. this.readyState = 0;
  17. this.url = url;
  18. this.io = new streams.IO(this);
  19. this.messages = new streams.Messages(this);
  20. this._bindEventListeners();
  21. };
  22. util.inherits(Base, Emitter);
  23. Base.validateOptions = function(options, validKeys) {
  24. for (var key in options) {
  25. if (validKeys.indexOf(key) < 0)
  26. throw new Error('Unrecognized option: ' + key);
  27. }
  28. };
  29. var instance = {
  30. // This is 64MB, small enough for an average VPS to handle without
  31. // crashing from process out of memory
  32. MAX_LENGTH: 0x3ffffff,
  33. STATES: ['connecting', 'open', 'closing', 'closed'],
  34. _bindEventListeners: function() {
  35. var self = this;
  36. // Protocol errors are informational and do not have to be handled
  37. this.messages.on('error', function() {});
  38. this.on('message', function(event) {
  39. var messages = self.messages;
  40. if (messages.readable) messages.emit('data', event.data);
  41. });
  42. this.on('error', function(error) {
  43. var messages = self.messages;
  44. if (messages.readable) messages.emit('error', error);
  45. });
  46. this.on('close', function() {
  47. var messages = self.messages;
  48. if (!messages.readable) return;
  49. messages.readable = messages.writable = false;
  50. messages.emit('end');
  51. });
  52. },
  53. getState: function() {
  54. return this.STATES[this.readyState] || null;
  55. },
  56. addExtension: function(extension) {
  57. return false;
  58. },
  59. setHeader: function(name, value) {
  60. if (this.readyState > 0) return false;
  61. this._headers.set(name, value);
  62. return true;
  63. },
  64. start: function() {
  65. if (this.readyState !== 0) return false;
  66. var response = this._handshakeResponse();
  67. if (!response) return false;
  68. this._write(response);
  69. if (this._stage !== -1) this._open();
  70. return true;
  71. },
  72. text: function(message) {
  73. return this.frame(message);
  74. },
  75. binary: function(message) {
  76. return false;
  77. },
  78. ping: function() {
  79. return false;
  80. },
  81. pong: function() {
  82. return false;
  83. },
  84. close: function(reason, code) {
  85. if (this.readyState !== 1) return false;
  86. this.readyState = 3;
  87. this.emit('close', new Base.CloseEvent(null, null));
  88. return true;
  89. },
  90. _open: function() {
  91. this.readyState = 1;
  92. this.__queue.forEach(function(args) { this.frame.apply(this, args) }, this);
  93. this.__queue = [];
  94. this.emit('open', new Base.OpenEvent());
  95. },
  96. _queue: function(message) {
  97. this.__queue.push(message);
  98. return true;
  99. },
  100. _write: function(chunk) {
  101. var io = this.io;
  102. if (io.readable) io.emit('data', chunk);
  103. }
  104. };
  105. for (var key in instance)
  106. Base.prototype[key] = instance[key];
  107. Base.ConnectEvent = function() {};
  108. Base.OpenEvent = function() {};
  109. Base.CloseEvent = function(code, reason) {
  110. this.code = code;
  111. this.reason = reason;
  112. };
  113. Base.MessageEvent = function(data) {
  114. this.data = data;
  115. };
  116. Base.PingEvent = function(data) {
  117. this.data = data;
  118. };
  119. Base.PongEvent = function(data) {
  120. this.data = data;
  121. };
  122. module.exports = Base;