Ein Projekt das es ermöglicht Beerpong über das Internet von zwei unabhängigen positionen aus zu spielen. Entstehung im Rahmen einer Praktikumsaufgabe im Fach Interaktion.
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.

Receiver.hixie.js 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*!
  2. * ws: a node.js websocket client
  3. * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
  4. * MIT Licensed
  5. */
  6. var util = require('util');
  7. /**
  8. * State constants
  9. */
  10. var EMPTY = 0
  11. , BODY = 1;
  12. var BINARYLENGTH = 2
  13. , BINARYBODY = 3;
  14. /**
  15. * Hixie Receiver implementation
  16. */
  17. function Receiver () {
  18. this.state = EMPTY;
  19. this.buffers = [];
  20. this.messageEnd = -1;
  21. this.spanLength = 0;
  22. this.dead = false;
  23. this.onerror = function() {};
  24. this.ontext = function() {};
  25. this.onbinary = function() {};
  26. this.onclose = function() {};
  27. this.onping = function() {};
  28. this.onpong = function() {};
  29. }
  30. module.exports = Receiver;
  31. /**
  32. * Add new data to the parser.
  33. *
  34. * @api public
  35. */
  36. Receiver.prototype.add = function(data) {
  37. var self = this;
  38. function doAdd() {
  39. if (self.state === EMPTY) {
  40. if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) {
  41. self.reset();
  42. self.onclose();
  43. return;
  44. }
  45. if (data[0] === 0x80) {
  46. self.messageEnd = 0;
  47. self.state = BINARYLENGTH;
  48. data = data.slice(1);
  49. } else {
  50. if (data[0] !== 0x00) {
  51. self.error('payload must start with 0x00 byte', true);
  52. return;
  53. }
  54. data = data.slice(1);
  55. self.state = BODY;
  56. }
  57. }
  58. if (self.state === BINARYLENGTH) {
  59. var i = 0;
  60. while ((i < data.length) && (data[i] & 0x80)) {
  61. self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
  62. ++i;
  63. }
  64. if (i < data.length) {
  65. self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
  66. self.state = BINARYBODY;
  67. ++i;
  68. }
  69. if (i > 0)
  70. data = data.slice(i);
  71. }
  72. if (self.state === BINARYBODY) {
  73. var dataleft = self.messageEnd - self.spanLength;
  74. if (data.length >= dataleft) {
  75. // consume the whole buffer to finish the frame
  76. self.buffers.push(data);
  77. self.spanLength += dataleft;
  78. self.messageEnd = dataleft;
  79. return self.parse();
  80. }
  81. // frame's not done even if we consume it all
  82. self.buffers.push(data);
  83. self.spanLength += data.length;
  84. return;
  85. }
  86. self.buffers.push(data);
  87. if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) {
  88. self.spanLength += self.messageEnd;
  89. return self.parse();
  90. }
  91. else self.spanLength += data.length;
  92. }
  93. while(data) data = doAdd();
  94. };
  95. /**
  96. * Releases all resources used by the receiver.
  97. *
  98. * @api public
  99. */
  100. Receiver.prototype.cleanup = function() {
  101. this.dead = true;
  102. this.state = EMPTY;
  103. this.buffers = [];
  104. };
  105. /**
  106. * Process buffered data.
  107. *
  108. * @api public
  109. */
  110. Receiver.prototype.parse = function() {
  111. var output = new Buffer(this.spanLength);
  112. var outputIndex = 0;
  113. for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) {
  114. var buffer = this.buffers[bi];
  115. buffer.copy(output, outputIndex);
  116. outputIndex += buffer.length;
  117. }
  118. var lastBuffer = this.buffers[this.buffers.length - 1];
  119. if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd);
  120. if (this.state !== BODY) --this.messageEnd;
  121. var tail = null;
  122. if (this.messageEnd < lastBuffer.length - 1) {
  123. tail = lastBuffer.slice(this.messageEnd + 1);
  124. }
  125. this.reset();
  126. this.ontext(output.toString('utf8'));
  127. return tail;
  128. };
  129. /**
  130. * Handles an error
  131. *
  132. * @api private
  133. */
  134. Receiver.prototype.error = function (reason, terminate) {
  135. this.reset();
  136. this.onerror(reason, terminate);
  137. return this;
  138. };
  139. /**
  140. * Reset parser state
  141. *
  142. * @api private
  143. */
  144. Receiver.prototype.reset = function (reason) {
  145. if (this.dead) return;
  146. this.state = EMPTY;
  147. this.buffers = [];
  148. this.messageEnd = -1;
  149. this.spanLength = 0;
  150. };
  151. /**
  152. * Internal api
  153. */
  154. function bufferIndex(buffer, byte) {
  155. for (var i = 0, l = buffer.length; i < l; ++i) {
  156. if (buffer[i] === byte) return i;
  157. }
  158. return -1;
  159. }