goog.labs.net.webChannel.WebChannelBase = function()

in closure/goog/labs/net/webchannel/webchannelbase.js [94:502]


goog.labs.net.webChannel.WebChannelBase = function(
    opt_options, opt_clientVersion, opt_conn) {
  'use strict';
  /**
   * The client library version (capabilities).
   * @private {number}
   */
  this.clientVersion_ = opt_clientVersion || 0;

  /**
   * The server library version (capabilities).
   * @private {number}
   */
  this.serverVersion_ = 0;


  /**
   * An array of queued maps that need to be sent to the server.
   * @private {!Array<Wire.QueuedMap>}
   */
  this.outgoingMaps_ = [];

  /**
   * The channel debug used for logging
   * @private {!WebChannelDebug}
   */
  this.channelDebug_ = new WebChannelDebug();

  /**
   * Connectivity state.
   * @private {!ConnectionState}
   */
  this.connState_ = opt_conn || new ConnectionState();

  /**
   * Extra HTTP headers to add to all the requests sent to the server.
   * @private {?Object}
   */
  this.extraHeaders_ = null;

  /**
   * Extra HTTP headers to add to the init request(s) sent to the server.
   * @private {?Object}
   */
  this.initHeaders_ = null;

  /**
   * @private {?string} The URL param name to overwrite custom HTTP headers
   * to bypass CORS preflight.
   */
  this.httpHeadersOverwriteParam_ = null;

  /**
   * Extra parameters to add to all the requests sent to the server.
   * @private {?Object}
   */
  this.extraParams_ = null;

  /**
   * Parameter name for the http session id.
   * @private {?string}
   */
  this.httpSessionIdParam_ = null;

  /**
   * The http session id, to be sent with httpSessionIdParam_ with each
   * request after the initial handshake.
   * @private {?string}
   */
  this.httpSessionId_ = null;

  /**
   * The ChannelRequest object for the backchannel.
   * @private {?ChannelRequest}
   */
  this.backChannelRequest_ = null;

  /**
   * The relative path (in the context of the page hosting the browser channel)
   * for making requests to the server.
   * @private {?string}
   */
  this.path_ = null;

  /**
   * The absolute URI for the forwardchannel request.
   * @private {?goog.Uri}
   */
  this.forwardChannelUri_ = null;

  /**
   * The absolute URI for the backchannel request.
   * @private {?goog.Uri}
   */
  this.backChannelUri_ = null;

  /**
   * A subdomain prefix for using a subdomain in IE for the backchannel
   * requests.
   * @private {?string}
   */
  this.hostPrefix_ = null;

  /**
   * Whether we allow the use of a subdomain in IE for the backchannel requests.
   * @private {boolean}
   */
  this.allowHostPrefix_ = true;

  /**
   * The next id to use for the RID (request identifier) parameter. This
   * identifier uniquely identifies the forward channel request.
   * @private {number}
   */
  this.nextRid_ = 0;

  /**
   * The id to use for the next outgoing map. This identifier uniquely
   * identifies a sent map.
   * @private {number}
   */
  this.nextMapId_ = 0;

  /**
   * Whether to fail forward-channel requests after one try or a few tries.
   * @private {boolean}
   */
  this.failFast_ = getInternalChannelParam('failFast', false, opt_options);

  /**
   * The handler that receive callbacks for state changes and data.
   * @private {?goog.labs.net.webChannel.WebChannelBase.Handler}
   */
  this.handler_ = null;

  /**
   * Timer identifier for asynchronously making a forward channel request.
   * This is set to true if the func is scheduled with async.run, which
   * is equivalent to setTimeout(0).
   * @private {?number|?boolean}
   */
  this.forwardChannelTimerId_ = null;

  /**
   * Timer identifier for asynchronously making a back channel request.
   * @private {?number}
   */
  this.backChannelTimerId_ = null;

  /**
   * Timer identifier for the timer that waits for us to retry the backchannel
   * in the case where it is dead and no longer receiving data.
   * @private {?number}
   */
  this.deadBackChannelTimerId_ = null;

  /**
   * Whether the client's network conditions can support streamed responses.
   * @private {?boolean}
   */
  this.enableStreaming_ = null;

  /**
   * Whether streaming mode is allowed. In certain debugging situations, it's
   * useful to disable this.
   * @private {boolean}
   */
  this.allowStreamingMode_ = true;

  /**
   * The array identifier of the last array received from the server for the
   * backchannel request.
   * @private {number}
   */
  this.lastArrayId_ = -1;

  /**
   * The array id of the last array sent by the server that we know about.
   * @private {number}
   */
  this.lastPostResponseArrayId_ = -1;

  /**
   * The last status code received (until `State.CLOSED` is reached).
   * @private {number}
   */
  this.lastStatusCode_ = -1;

  /**
   * Number of times we have retried the current forward channel request.
   * @private {number}
   */
  this.forwardChannelRetryCount_ = 0;

  /**
   * Number of times in a row that we have retried the current back channel
   * request and received no data.
   * @private {number}
   */
  this.backChannelRetryCount_ = 0;

  /**
   * The attempt id for the current back channel request. Starts at 1 and
   * increments for each reconnect. The server uses this to log if our
   * connection is flaky or not.
   * @private {number}
   */
  this.backChannelAttemptId_ = 0;

  /**
   * The base part of the time before firing next retry request. Default is 5
   * seconds. Note that a random delay is added (see {@link retryDelaySeedMs_})
   * for all retries, and linear backoff is applied to the sum for subsequent
   * retries.
   * @private {number}
   */
  this.baseRetryDelayMs_ =
      getInternalChannelParam('baseRetryDelayMs', 5 * 1000, opt_options);

  /**
   * A random time between 0 and this number of MS is added to the
   * {@link baseRetryDelayMs_}. Default is 10 seconds.
   * @private {number}
   */
  this.retryDelaySeedMs_ =
      getInternalChannelParam('retryDelaySeedMs', 10 * 1000, opt_options);

  /**
   * Maximum number of attempts to connect to the server for forward channel
   * requests. Defaults to 2.
   * @private {number}
   */
  this.forwardChannelMaxRetries_ =
      getInternalChannelParam('forwardChannelMaxRetries', 2, opt_options);

  /**
   * The timeout in milliseconds for a forward channel request. Defaults to 20
   * seconds. Note that part of this timeout can be randomized.
   * @private {number}
   */
  this.forwardChannelRequestTimeoutMs_ = getInternalChannelParam(
      'forwardChannelRequestTimeoutMs', 20 * 1000, opt_options);

  /**
   * The custom factory used to create XMLHttpRequest objects.
   * @private {!goog.net.XmlHttpFactory | undefined}
   */
  this.xmlHttpFactory_ =
      (opt_options && opt_options.xmlHttpFactory) || undefined;

  /**
   * Whether or not this channel uses WHATWG Fetch/streams.
   * @private {boolean}
   */
  this.usesFetchStreams_ =
      (opt_options && opt_options.useFetchStreams) || false;

  /**
   * The timeout in milliseconds for a back channel request. Defaults to using
   * the timeout configured in ChannelRequest (45s). If server-side
   * keepaliveInterval is known to the client, set the backchannel request
   * timeout to 1.5 * keepaliveInterval (ms).
   *
   * @private {number|undefined}
   */
  this.backChannelRequestTimeoutMs_ = undefined;

  /**
   * A throttle time in ms for readystatechange events for the backchannel.
   * Useful for throttling when ready state is INTERACTIVE (partial data).
   *
   * This throttle is useful if the server sends large data chunks down the
   * backchannel.  It prevents examining XHR partial data on every readystate
   * change event.  This is useful because large chunks can trigger hundreds
   * of readystatechange events, each of which takes ~5ms or so to handle,
   * in turn making the UI unresponsive for a significant period.
   *
   * If set to zero no throttle is used.
   * @private {number}
   */
  this.readyStateChangeThrottleMs_ = 0;

  /**
   * Whether cross origin requests are supported for the channel.
   *
   * See {@link goog.net.XhrIo#setWithCredentials}.
   * @private {boolean}
   */
  this.supportsCrossDomainXhrs_ =
      (opt_options && opt_options.supportsCrossDomainXhr) || false;

  /**
   * The current session id.
   * @private {string}
   */
  this.sid_ = '';

  /**
   * The current ChannelRequest pool for the forward channel.
   * @private {!ForwardChannelRequestPool}
   */
  this.forwardChannelRequestPool_ = new ForwardChannelRequestPool(
      opt_options && opt_options.concurrentRequestLimit);

  /**
   * The V8 codec.
   * @private {!WireV8}
   */
  this.wireCodec_ = new WireV8();

  /**
   * Whether to turn on the fast handshake behavior.
   *
   * @private {boolean}
   */
  this.fastHandshake_ = (opt_options && opt_options.fastHandshake) || false;

  /**
   * Whether to encode initMessageHeaders in the body.
   *
   * @private {boolean}
   */
  this.encodeInitMessageHeaders_ =
      (opt_options && opt_options.encodeInitMessageHeaders) || false;

  if (this.fastHandshake_ && this.encodeInitMessageHeaders_) {
    this.channelDebug_.warning(
        'Ignore encodeInitMessageHeaders because fastHandshake is set.');
    this.encodeInitMessageHeaders_ = false;
  }

  /**
   * Whether to signal to the server to enable blocking handshake.
   *
   * @private {boolean}
   */
  this.blockingHandshake_ =
      (opt_options && opt_options.blockingHandshake) || false;


  if (opt_options && opt_options.disableRedact) {
    this.channelDebug_.disableRedact();
  }

  if (opt_options && opt_options.forceLongPolling) {
    this.allowStreamingMode_ = false;
  }

  /**
   * Whether to detect buffering proxies.
   *
   * fastHandshake + detectBufferingProxy are yet to be implemented.
   *
   * @private {boolean}
   */
  this.detectBufferingProxy_ =
      (!this.fastHandshake_ && this.allowStreamingMode_ && opt_options &&
       opt_options.detectBufferingProxy) ||
      false;

  /**
   * Callback when all the pending client-sent messages have been flushed.
   *
   * @private {function()|undefined}
   */
  this.forwardChannelFlushedCallback_ = undefined;

  /**
   * TODO(user): move all backchannel states to its own class similar to
   * forwardchannelrequestpool.js and log more stats.
   *
   * The estimated handshake RTT (ms) as measured from when the handshake
   * request is sent and when the handshake response headers are received.
   * If the value is 0, the RTT is unknown.
   *
   * @private {number}
   */
  this.handshakeRttMs_ = 0;

  /**
   * If BP detection is done or still in progress.
   * Should only be checked when detectBufferingProxy is turned on.
   * @private {boolean}
   */
  this.bpDetectionDone_ = false;

  /**
   * The timer for detecting buffering proxy. This needs be reset with each
   * backchannel request. If this is not null, bpDetectionDone_ == false.
   * @private {?number}
   */
  this.bpDetectionTimerId_ = null;

  /***
   * Whether to attempt Chrome Origin Trials as part of the handshake.
   * @private @const {boolean}
   */
  this.enableOriginTrials_ = ALLOW_ORIGIN_TRIAL_FEATURES &&
      (!opt_options || opt_options.enableOriginTrials !== false);

  /**
   * The array of non-acked maps at the time of channel close. Refer to
   * `getNonAckedMessagesWithClosedChannel()` API for definitions of non-acked
   * messages.
   *
   * @private {?Array<!Wire.QueuedMap>}
   */
  this.nonAckedMapsAtChannelClose_ = null;
};