123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- // Copyright 2013 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Implementation of a WebChannel transport using WebChannelBase.
- *
- * When WebChannelBase is used as the underlying transport, the capabilities
- * of the WebChannel are limited to what's supported by the implementation.
- * Particularly, multiplexing is not possible, and only strings are
- * supported as message types.
- *
- */
- goog.provide('goog.labs.net.webChannel.WebChannelBaseTransport');
- goog.require('goog.asserts');
- goog.require('goog.events.EventTarget');
- goog.require('goog.json');
- goog.require('goog.labs.net.webChannel.ChannelRequest');
- goog.require('goog.labs.net.webChannel.WebChannelBase');
- goog.require('goog.log');
- goog.require('goog.net.WebChannel');
- goog.require('goog.net.WebChannelTransport');
- goog.require('goog.object');
- goog.require('goog.string');
- goog.require('goog.string.path');
- /**
- * Implementation of {@link goog.net.WebChannelTransport} with
- * {@link goog.labs.net.webChannel.WebChannelBase} as the underlying channel
- * implementation.
- *
- * @constructor
- * @struct
- * @implements {goog.net.WebChannelTransport}
- * @final
- */
- goog.labs.net.webChannel.WebChannelBaseTransport = function() {
- if (!goog.labs.net.webChannel.ChannelRequest.supportsXhrStreaming()) {
- throw new Error('Environmental error: no available transport.');
- }
- };
- goog.scope(function() {
- var WebChannelBaseTransport = goog.labs.net.webChannel.WebChannelBaseTransport;
- var WebChannelBase = goog.labs.net.webChannel.WebChannelBase;
- /**
- * @override
- */
- WebChannelBaseTransport.prototype.createWebChannel = function(
- url, opt_options) {
- return new WebChannelBaseTransport.Channel(url, opt_options);
- };
- /**
- * Implementation of the {@link goog.net.WebChannel} interface.
- *
- * @param {string} url The URL path for the new WebChannel instance.
- * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the
- * new WebChannel instance.
- *
- * @constructor
- * @implements {goog.net.WebChannel}
- * @extends {goog.events.EventTarget}
- * @final
- */
- WebChannelBaseTransport.Channel = function(url, opt_options) {
- WebChannelBaseTransport.Channel.base(this, 'constructor');
- /**
- * @private {!WebChannelBase} The underlying channel object.
- */
- this.channel_ = new WebChannelBase(
- opt_options, goog.net.WebChannelTransport.CLIENT_VERSION);
- /**
- * @private {string} The URL of the target server end-point.
- */
- this.url_ = url;
- /**
- * The test URL of the target server end-point. This value defaults to
- * this.url_ + '/test'.
- *
- * @private {string}
- */
- this.testUrl_ = (opt_options && opt_options.testUrl) ?
- opt_options.testUrl :
- goog.string.path.join(this.url_, 'test');
- /**
- * @private {goog.log.Logger} The logger for this class.
- */
- this.logger_ =
- goog.log.getLogger('goog.labs.net.webChannel.WebChannelBaseTransport');
- /**
- * @private {Object<string, string>} Extra URL parameters
- * to be added to each HTTP request.
- */
- this.messageUrlParams_ =
- (opt_options && opt_options.messageUrlParams) || null;
- var messageHeaders = (opt_options && opt_options.messageHeaders) || null;
- // default is false
- if (opt_options && opt_options.clientProtocolHeaderRequired) {
- if (messageHeaders) {
- goog.object.set(
- messageHeaders, goog.net.WebChannel.X_CLIENT_PROTOCOL,
- goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);
- } else {
- messageHeaders = goog.object.create(
- goog.net.WebChannel.X_CLIENT_PROTOCOL,
- goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);
- }
- }
- this.channel_.setExtraHeaders(messageHeaders);
- var initHeaders = (opt_options && opt_options.initMessageHeaders) || null;
- this.channel_.setInitHeaders(initHeaders);
- var httpHeadersOverwriteParam =
- opt_options && opt_options.httpHeadersOverwriteParam;
- if (httpHeadersOverwriteParam &&
- !goog.string.isEmptyOrWhitespace(httpHeadersOverwriteParam)) {
- this.channel_.setHttpHeadersOverwriteParam(httpHeadersOverwriteParam);
- }
- /**
- * @private {boolean} Whether to enable CORS.
- */
- this.supportsCrossDomainXhr_ =
- (opt_options && opt_options.supportsCrossDomainXhr) || false;
- /**
- * @private {boolean} Whether to send raw Json and bypass v8 wire format.
- */
- this.sendRawJson_ = (opt_options && opt_options.sendRawJson) || false;
- // Note that httpSessionIdParam will be ignored if the same parameter name
- // has already been specified with messageUrlParams
- var httpSessionIdParam = opt_options && opt_options.httpSessionIdParam;
- if (httpSessionIdParam &&
- !goog.string.isEmptyOrWhitespace(httpSessionIdParam)) {
- this.channel_.setHttpSessionIdParam(httpSessionIdParam);
- if (goog.object.containsKey(this.messageUrlParams_, httpSessionIdParam)) {
- goog.object.remove(this.messageUrlParams_, httpSessionIdParam);
- goog.log.warning(this.logger_,
- 'Ignore httpSessionIdParam also specified with messageUrlParams: '
- + httpSessionIdParam);
- }
- }
- /**
- * The channel handler.
- *
- * @private {!WebChannelBaseTransport.Channel.Handler_}
- */
- this.channelHandler_ = new WebChannelBaseTransport.Channel.Handler_(this);
- };
- goog.inherits(WebChannelBaseTransport.Channel, goog.events.EventTarget);
- /**
- * @override
- * @suppress {checkTypes}
- */
- WebChannelBaseTransport.Channel.prototype.addEventListener = function(
- type, handler, /** boolean= */ opt_capture, opt_handlerScope) {
- WebChannelBaseTransport.Channel.base(
- this, 'addEventListener', type, handler, opt_capture, opt_handlerScope);
- };
- /**
- * @override
- * @suppress {checkTypes}
- */
- WebChannelBaseTransport.Channel.prototype.removeEventListener = function(
- type, handler, /** boolean= */ opt_capture, opt_handlerScope) {
- WebChannelBaseTransport.Channel.base(
- this, 'removeEventListener', type, handler, opt_capture,
- opt_handlerScope);
- };
- /**
- * Test path is always set to "/url/test".
- *
- * @override
- */
- WebChannelBaseTransport.Channel.prototype.open = function() {
- this.channel_.setHandler(this.channelHandler_);
- if (this.supportsCrossDomainXhr_) {
- this.channel_.setSupportsCrossDomainXhrs(true);
- }
- this.channel_.connect(
- this.testUrl_, this.url_, (this.messageUrlParams_ || undefined));
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.prototype.close = function() {
- this.channel_.disconnect();
- };
- /**
- * The WebChannelBase only supports object types.
- *
- * @param {!goog.net.WebChannel.MessageData} message The message to send.
- *
- * @override
- */
- WebChannelBaseTransport.Channel.prototype.send = function(message) {
- goog.asserts.assert(goog.isObject(message), 'only object type expected');
- if (this.sendRawJson_) {
- var rawJson = {};
- rawJson['__data__'] = goog.json.serialize(message);
- this.channel_.sendMap(rawJson);
- } else {
- this.channel_.sendMap(message);
- }
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.prototype.disposeInternal = function() {
- this.channel_.setHandler(null);
- delete this.channelHandler_;
- this.channel_.disconnect();
- delete this.channel_;
- WebChannelBaseTransport.Channel.base(this, 'disposeInternal');
- };
- /**
- * The message event.
- *
- * @param {!Array<?>} array The data array from the underlying channel.
- * @constructor
- * @extends {goog.net.WebChannel.MessageEvent}
- * @final
- */
- WebChannelBaseTransport.Channel.MessageEvent = function(array) {
- WebChannelBaseTransport.Channel.MessageEvent.base(this, 'constructor');
- this.data = array;
- };
- goog.inherits(
- WebChannelBaseTransport.Channel.MessageEvent,
- goog.net.WebChannel.MessageEvent);
- /**
- * The error event.
- *
- * @param {WebChannelBase.Error} error The error code.
- * @constructor
- * @extends {goog.net.WebChannel.ErrorEvent}
- * @final
- */
- WebChannelBaseTransport.Channel.ErrorEvent = function(error) {
- WebChannelBaseTransport.Channel.ErrorEvent.base(this, 'constructor');
- /**
- * High-level status code.
- */
- this.status = goog.net.WebChannel.ErrorStatus.NETWORK_ERROR;
- /**
- * @const {WebChannelBase.Error} Internal error code, for debugging use only.
- */
- this.errorCode = error;
- };
- goog.inherits(
- WebChannelBaseTransport.Channel.ErrorEvent, goog.net.WebChannel.ErrorEvent);
- /**
- * Implementation of {@link WebChannelBase.Handler} interface.
- *
- * @param {!WebChannelBaseTransport.Channel} channel The enclosing WebChannel.
- *
- * @constructor
- * @extends {WebChannelBase.Handler}
- * @private
- */
- WebChannelBaseTransport.Channel.Handler_ = function(channel) {
- WebChannelBaseTransport.Channel.Handler_.base(this, 'constructor');
- /**
- * @type {!WebChannelBaseTransport.Channel}
- * @private
- */
- this.channel_ = channel;
- };
- goog.inherits(WebChannelBaseTransport.Channel.Handler_, WebChannelBase.Handler);
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.Handler_.prototype.channelOpened = function(
- channel) {
- goog.log.info(
- this.channel_.logger_, 'WebChannel opened on ' + this.channel_.url_);
- this.channel_.dispatchEvent(goog.net.WebChannel.EventType.OPEN);
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.Handler_.prototype.channelHandleArray =
- function(channel, array) {
- goog.asserts.assert(array, 'array expected to be defined');
- this.channel_.dispatchEvent(
- new WebChannelBaseTransport.Channel.MessageEvent(array));
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.Handler_.prototype.channelError = function(
- channel, error) {
- goog.log.info(
- this.channel_.logger_, 'WebChannel aborted on ' + this.channel_.url_ +
- ' due to channel error: ' + error);
- this.channel_.dispatchEvent(
- new WebChannelBaseTransport.Channel.ErrorEvent(error));
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.Handler_.prototype.channelClosed = function(
- channel, opt_pendingMaps, opt_undeliveredMaps) {
- goog.log.info(
- this.channel_.logger_, 'WebChannel closed on ' + this.channel_.url_);
- this.channel_.dispatchEvent(goog.net.WebChannel.EventType.CLOSE);
- };
- /**
- * @override
- */
- WebChannelBaseTransport.Channel.prototype.getRuntimeProperties = function() {
- return new WebChannelBaseTransport.ChannelProperties(this.channel_);
- };
- /**
- * Implementation of the {@link goog.net.WebChannel.RuntimeProperties}.
- *
- * @param {!WebChannelBase} channel The underlying channel object.
- *
- * @constructor
- * @implements {goog.net.WebChannel.RuntimeProperties}
- * @final
- */
- WebChannelBaseTransport.ChannelProperties = function(channel) {
- /**
- * The underlying channel object.
- *
- * @private {!WebChannelBase}
- */
- this.channel_ = channel;
- };
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.getConcurrentRequestLimit =
- function() {
- return this.channel_.getForwardChannelRequestPool().getMaxSize();
- };
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.isSpdyEnabled = function() {
- return this.getConcurrentRequestLimit() > 1;
- };
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.getHttpSessionId =
- function() {
- return this.channel_.getHttpSessionId();
- };
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.commit =
- goog.abstractMethod;
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.getNonAckedMessageCount =
- goog.abstractMethod;
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.notifyNonAckedMessageCount =
- goog.abstractMethod;
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.onCommit =
- goog.abstractMethod;
- /**
- * @override
- */
- WebChannelBaseTransport.ChannelProperties.prototype.ackCommit =
- goog.abstractMethod;
- /** @override */
- WebChannelBaseTransport.ChannelProperties.prototype.getLastStatusCode =
- function() {
- return this.channel_.getLastStatusCode();
- };
- }); // goog.scope
|