twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

websocket.js (2456B)


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