dispatch(data, compress, options, cb) {
    if (!compress) {
      this.sendFrame(Sender.frame(data, options), cb);
      return;
    }

    const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];

    this._bufferedBytes += options[kByteLength];
    this._state = DEFLATING;
    perMessageDeflate.compress(data, options.fin, (_, buf) => {
      if (this._socket.destroyed) {
        const err = new Error(
          'The socket was closed while data was being compressed'
        );

        callCallbacks(this, err, cb);
        return;
      }

      this._bufferedBytes -= options[kByteLength];
      this._state = DEFAULT;
      options.readOnly = false;
      this.sendFrame(Sender.frame(buf, options), cb);
      this.dequeue();
    });
  }
Dispatches a message.

@param {(Buffer|String)} data The message to send
@param {Boolean} [compress=false] Specifies whether or not to compress
    `data`
@param {Object} options Options object
@param {Boolean} [options.fin=false] Specifies whether or not to set the
    FIN bit
@param {Function} [options.generateMask] The function used to generate the
    masking key
@param {Boolean} [options.mask=false] Specifies whether or not to mask
    `data`
@param {Buffer} [options.maskBuffer] The buffer used to store the masking
    key
@param {Number} options.opcode The opcode
@param {Boolean} [options.readOnly=false] Specifies whether `data` can be
    modified
@param {Boolean} [options.rsv1=false] Specifies whether or not to set the
    RSV1 bit
@param {Function} [cb] Callback
@private