websocket.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * Module dependencies.
  3. */
  4. var Transport = require('../transport')
  5. , parser = require('engine.io-parser')
  6. , debug = require('debug')('engine:ws')
  7. /**
  8. * Export the constructor.
  9. */
  10. module.exports = WebSocket;
  11. /**
  12. * WebSocket transport
  13. *
  14. * @param {http.ServerRequest}
  15. * @api public
  16. */
  17. function WebSocket (req) {
  18. Transport.call(this, req);
  19. var self = this;
  20. this.socket = req.websocket;
  21. this.socket.on('message', this.onData.bind(this));
  22. this.socket.once('close', this.onClose.bind(this));
  23. this.socket.on('error', this.onError.bind(this));
  24. this.socket.on('headers', function (headers) {
  25. self.emit('headers', headers);
  26. });
  27. this.writable = true;
  28. this.perMessageDeflate = null;
  29. };
  30. /**
  31. * Inherits from Transport.
  32. */
  33. WebSocket.prototype.__proto__ = Transport.prototype;
  34. /**
  35. * Transport name
  36. *
  37. * @api public
  38. */
  39. WebSocket.prototype.name = 'websocket';
  40. /**
  41. * Advertise upgrade support.
  42. *
  43. * @api public
  44. */
  45. WebSocket.prototype.handlesUpgrades = true;
  46. /**
  47. * Advertise framing support.
  48. *
  49. * @api public
  50. */
  51. WebSocket.prototype.supportsFraming = true;
  52. /**
  53. * Processes the incoming data.
  54. *
  55. * @param {String} encoded packet
  56. * @api private
  57. */
  58. WebSocket.prototype.onData = function (data) {
  59. debug('received "%s"', data);
  60. Transport.prototype.onData.call(this, data);
  61. };
  62. /**
  63. * Writes a packet payload.
  64. *
  65. * @param {Array} packets
  66. * @api private
  67. */
  68. WebSocket.prototype.send = function (packets) {
  69. var self = this;
  70. packets.forEach(function(packet) {
  71. parser.encodePacket(packet, self.supportsBinary, function(data) {
  72. debug('writing "%s"', data);
  73. // always creates a new object since ws modifies it
  74. var opts = {};
  75. if (packet.options) {
  76. opts.compress = packet.options.compress;
  77. }
  78. if (self.perMessageDeflate) {
  79. var len = 'string' == typeof data ? Buffer.byteLength(data) : data.length;
  80. if (len < self.perMessageDeflate.threshold) {
  81. opts.compress = false;
  82. }
  83. }
  84. self.writable = false;
  85. self.socket.send(data, opts, function (err){
  86. if (err) return self.onError('write error', err.stack);
  87. self.writable = true;
  88. self.emit('drain');
  89. });
  90. });
  91. });
  92. };
  93. /**
  94. * Closes the transport.
  95. *
  96. * @api private
  97. */
  98. WebSocket.prototype.doClose = function (fn) {
  99. debug('closing');
  100. this.socket.close();
  101. fn && fn();
  102. };