Path: blob/trunk/third_party/closure/goog/labs/net/webchannel.js
2868 views
// Copyright 2013 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview The API spec for the WebChannel messaging library.16*17* Similar to HTML5 WebSocket and Closure BrowserChannel, WebChannel18* offers an abstraction for point-to-point socket-like communication between19* a browser client and a remote origin.20*21* WebChannels are created via <code>WebChannel</code>. Multiple WebChannels22* may be multiplexed over the same WebChannelTransport, which represents23* the underlying physical connectivity over standard wire protocols24* such as HTTP and SPDY.25*26* A WebChannels in turn represents a logical communication channel between27* the client and server end point. A WebChannel remains open for28* as long as the client or server end-point allows.29*30* Messages may be delivered in-order or out-of-order, reliably or unreliably31* over the same WebChannel. Message delivery guarantees of a WebChannel is32* to be specified by the application code; and the choice of the33* underlying wire protocols is completely transparent to the API users.34*35* Client-to-client messaging via WebRTC based transport may also be support36* via the same WebChannel API in future.37*38* Note that we have no immediate plan to move this API out of labs. While39* the implementation is production ready, the API is subject to change40* (addition only):41* 1. Adopt new Web APIs (mainly whatwg streams) and goog.net.streams.42* 2. New programming models for cloud (on the server-side) may require43* new APIs to be defined.44* 3. WebRTC DataChannel alignment45*46*/4748goog.provide('goog.net.WebChannel');4950goog.require('goog.events');51goog.require('goog.events.Event');52535455/**56* A WebChannel represents a logical bi-directional channel over which the57* client communicates with a remote server that holds the other endpoint58* of the channel. A WebChannel is always created in the context of a shared59* {@link WebChannelTransport} instance. It is up to the underlying client-side60* and server-side implementations to decide how or when multiplexing is61* to be enabled.62*63* @interface64* @extends {EventTarget}65*/66goog.net.WebChannel = function() {};676869/**70* Configuration spec for newly created WebChannel instances.71*72* WebChannels are configured in the context of the containing73* {@link WebChannelTransport}. The configuration parameters are specified74* when a new instance of WebChannel is created via {@link WebChannelTransport}.75*76* messageHeaders: custom headers to be added to every message sent to the77* server. This object is mutable, and custom headers may be changed, removed,78* or added during the runtime after a channel has been opened.79*80* initMessageHeaders: similar to messageHeaders, but any custom headers will81* be sent only once when the channel is opened. Typical usage is to send82* an auth header to the server, which only checks the auth header at the time83* when the channel is opened.84*85* messageUrlParams: custom url query parameters to be added to every message86* sent to the server. This object is mutable, and custom parameters may be87* changed, removed or added during the runtime after a channel has been opened.88*89* clientProtocolHeaderRequired: whether a special header should be added to90* each message so that the server can dispatch webchannel messages without91* knowing the URL path prefix. Defaults to false.92*93* concurrentRequestLimit: the maximum number of in-flight HTTP requests allowed94* when SPDY is enabled. Currently we only detect SPDY in Chrome.95* This parameter defaults to 10. When SPDY is not enabled, this parameter96* will have no effect.97*98* supportsCrossDomainXhr: setting this to true to allow the use of sub-domains99* (as configured by the server) to send XHRs with the CORS withCredentials100* bit set to true.101*102* testUrl: the test URL for detecting connectivity during the initial103* handshake. This parameter defaults to "/<channel_url>/test".104*105* sendRawJson: whether to bypass v8 encoding of client-sent messages. Will be106* deprecated after v9 wire protocol is introduced. Only safe to set if the107* server is known to support this feature.108*109* httpSessionIdParam: the URL parameter name that contains the session id (110* for sticky routing of HTTP requests). When this param is specified, a server111* that supports this option will respond with an opaque session id as part of112* the initial handshake (via the X-HTTP-Session-Id header); and all the113* subsequent requests will contain the httpSessionIdParam. This option will114* take precedence over any duplicated parameter specified with115* messageUrlParams, whose value will be ignored.116*117* httpHeadersOverwriteParam: the URL parameter name to allow custom HTTP118* headers to be overwritten as a URL param to bypass CORS preflight.119* goog.net.rpc.HttpCors is used to encode the HTTP headers.120*121* backgroundChannelTest: whether to run the channel test (detecting networking122* conditions) as a background process so the OPEN event will be fired sooner123* to reduce the initial handshake delay. This option defaults to false now.124* Eventually we may turn this flag on by default.125*126* @typedef {{127* messageHeaders: (!Object<string, string>|undefined),128* initMessageHeaders: (!Object<string, string>|undefined),129* messageUrlParams: (!Object<string, string>|undefined),130* clientProtocolHeaderRequired: (boolean|undefined),131* concurrentRequestLimit: (number|undefined),132* supportsCrossDomainXhr: (boolean|undefined),133* testUrl: (string|undefined),134* sendRawJson: (boolean|undefined),135* httpSessionIdParam: (string|undefined),136* httpHeadersOverwriteParam: (string|undefined),137* backgroundChannelTest: (boolean|undefined)138* }}139*/140goog.net.WebChannel.Options;141142143/**144* Types that are allowed as message data.145*146* Note that JS objects (sent by the client) can only have string encoded147* values due to the limitation of the current wire protocol.148*149* Unicode strings (sent by the server) may or may not need be escaped, as150* decided by the server.151*152* @typedef {(ArrayBuffer|Blob|Object<string, string>|Array)}153*/154goog.net.WebChannel.MessageData;155156157/**158* Open the WebChannel against the URI specified in the constructor.159*/160goog.net.WebChannel.prototype.open = goog.abstractMethod;161162163/**164* Close the WebChannel.165*/166goog.net.WebChannel.prototype.close = goog.abstractMethod;167168169/**170* Sends a message to the server that maintains the other end point of171* the WebChannel.172*173* @param {!goog.net.WebChannel.MessageData} message The message to send.174*/175goog.net.WebChannel.prototype.send = goog.abstractMethod;176177178/**179* Common events fired by WebChannels.180* @enum {string}181*/182goog.net.WebChannel.EventType = {183/** Dispatched when the channel is opened. */184OPEN: goog.events.getUniqueId('open'),185186/** Dispatched when the channel is closed. */187CLOSE: goog.events.getUniqueId('close'),188189/** Dispatched when the channel is aborted due to errors. */190ERROR: goog.events.getUniqueId('error'),191192/** Dispatched when the channel has received a new message. */193MESSAGE: goog.events.getUniqueId('message')194};195196197198/**199* The event interface for the MESSAGE event.200*201* @constructor202* @extends {goog.events.Event}203*/204goog.net.WebChannel.MessageEvent = function() {205goog.net.WebChannel.MessageEvent.base(206this, 'constructor', goog.net.WebChannel.EventType.MESSAGE);207};208goog.inherits(goog.net.WebChannel.MessageEvent, goog.events.Event);209210211/**212* The content of the message received from the server.213*214* @type {!goog.net.WebChannel.MessageData}215*/216goog.net.WebChannel.MessageEvent.prototype.data;217218219/**220* WebChannel level error conditions.221*222* Summary of error debugging and reporting in WebChannel:223*224* Network Error225* 1. By default the webchannel library will set the error status to226* NETWORK_ERROR when a channel has to be aborted or closed. NETWORK_ERROR227* may be recovered by the application by retrying and opening a new channel.228* 2. There may be lost messages (not acked by the server) when a channel is229* aborted. Currently we don't have a public API to retrieve messages that230* are waiting to be acked on the client side. File a bug if you think it231* is useful to expose such an API.232* 3. Details of why a channel fails are available via closure debug logs,233* and stats events (see webchannel/requeststats.js). Those are internal234* stats and are subject to change. File a bug if you think it's useful to235* version and expose such stats as part of the WebChannel API.236*237* Server Error238* 1. SERVER_ERROR is intended to indicate a non-recoverable condition, e.g.239* when auth fails.240* 2. We don't currently generate any such errors, because most of the time241* it's the responsibility of upper-layer frameworks or the application242* itself to indicate to the client why a webchannel has been failed243* by the server.244* 3. When a channel is failed by the server explicitly, we still signal245* NETWORK_ERROR to the client. Explicit server failure may happen when the246* server does a fail-over, or becomes overloaded, or conducts a forced247* shutdown etc.248* 4. We use some heuristic to decide if the network (aka cloud) is down249* v.s. the actual server is down.250*251* RuntimeProperties.getLastStatusCode is a useful state that we expose to252* the client to indicate the HTTP response status code of the last HTTP253* request initiated by the WebChannel client library, for debugging254* purposes only.255*256* @enum {number}257*/258goog.net.WebChannel.ErrorStatus = {259/** No error has occurred. */260OK: 0,261262/** Communication to the server has failed. */263NETWORK_ERROR: 1,264265/** The server fails to accept or process the WebChannel. */266SERVER_ERROR: 2267};268269270271/**272* The event interface for the ERROR event.273*274* @constructor275* @extends {goog.events.Event}276*/277goog.net.WebChannel.ErrorEvent = function() {278goog.net.WebChannel.ErrorEvent.base(279this, 'constructor', goog.net.WebChannel.EventType.ERROR);280};281goog.inherits(goog.net.WebChannel.ErrorEvent, goog.events.Event);282283284/**285* The error status.286*287* @type {!goog.net.WebChannel.ErrorStatus}288*/289goog.net.WebChannel.ErrorEvent.prototype.status;290291292/**293* @return {!goog.net.WebChannel.RuntimeProperties} The runtime properties294* of the WebChannel instance.295*/296goog.net.WebChannel.prototype.getRuntimeProperties = goog.abstractMethod;297298299300/**301* The runtime properties of the WebChannel instance.302*303* This class is defined for debugging and monitoring purposes, as well as for304* runtime functions that the application may choose to manage by itself.305*306* @interface307*/308goog.net.WebChannel.RuntimeProperties = function() {};309310311/**312* @return {number} The effective limit for the number of concurrent HTTP313* requests that are allowed to be made for sending messages from the client314* to the server. When SPDY is not enabled, this limit will be one.315*/316goog.net.WebChannel.RuntimeProperties.prototype.getConcurrentRequestLimit =317goog.abstractMethod;318319320/**321* For applications that need support multiple channels (e.g. from322* different tabs) to the same origin, use this method to decide if SPDY is323* enabled and therefore it is safe to open multiple channels.324*325* If SPDY is disabled, the application may choose to limit the number of active326* channels to one or use other means such as sub-domains to work around327* the browser connection limit.328*329* @return {boolean} Whether SPDY is enabled for the origin against which330* the channel is created.331*/332goog.net.WebChannel.RuntimeProperties.prototype.isSpdyEnabled =333goog.abstractMethod;334335336/**337* For applications to query the current HTTP session id, sent by the server338* during the initial handshake.339*340* @return {?string} the HTTP session id or null if no HTTP session is in use.341*/342goog.net.WebChannel.RuntimeProperties.prototype.getHttpSessionId =343goog.abstractMethod;344345346/**347* This method generates an in-band commit request to the server, which will348* ack the commit request as soon as all messages sent prior to this commit349* request have been committed by the application.350*351* Committing a message has a stronger semantics than delivering a message352* to the application. Detail spec:353* https://github.com/bidiweb/webchannel/blob/master/commit.md354*355* Timeout or cancellation is not supported and the application may have to356* abort the channel if the commit-ack fails to arrive in time.357*358* @param {function()} callback The callback will be invoked once an359* ack has been received for the current commit or any newly issued commit.360*/361goog.net.WebChannel.RuntimeProperties.prototype.commit = goog.abstractMethod;362363364/**365* This method may be used by the application to recover from a peer failure366* or to enable sender-initiated flow-control.367*368* Detail spec: https://github.com/bidiweb/webchannel/blob/master/commit.md369*370* @return {number} The total number of messages that have not received371* commit-ack from the server; or if no commit has been issued, the number372* of messages that have not been delivered to the server application.373*/374goog.net.WebChannel.RuntimeProperties.prototype.getNonAckedMessageCount =375goog.abstractMethod;376377378/**379* A low water-mark message count to notify the application when the380* flow-control condition is cleared, that is, when the application is381* able to send more messages.382*383* We expect the application to configure a high water-mark message count,384* which is checked via getNonAckedMessageCount(). When the high water-mark385* is exceeded, the application should install a callback via this method386* to be notified when to start to send new messages.387*388* @param {number} count The low water-mark count. It is an error to pass389* a non-positive value.390* @param {!function()} callback The call back to notify the application391* when NonAckedMessageCount is below the specified low water-mark count.392* Any previously registered callback is cleared. This new callback will393* be cleared once it has been fired, or when the channel is closed or aborted.394*/395goog.net.WebChannel.RuntimeProperties.prototype.notifyNonAckedMessageCount =396goog.abstractMethod;397398399/**400* This method registers a callback to handle the commit request sent401* by the server. Commit protocol spec:402* https://github.com/bidiweb/webchannel/blob/master/commit.md403*404* @param {function(!Object)} callback The callback will take an opaque405* commitId which needs be passed back to the server when an ack-commit406* response is generated by the client application, via ackCommit().407*/408goog.net.WebChannel.RuntimeProperties.prototype.onCommit = goog.abstractMethod;409410411/**412* This method is used by the application to generate an ack-commit response413* for the given commitId. Commit protocol spec:414* https://github.com/bidiweb/webchannel/blob/master/commit.md415*416* @param {!Object} commitId The commitId which denotes the commit request417* from the server that needs be ack'ed.418*/419goog.net.WebChannel.RuntimeProperties.prototype.ackCommit = goog.abstractMethod;420421422/**423* @return {number} The last HTTP status code received by the channel.424*/425goog.net.WebChannel.RuntimeProperties.prototype.getLastStatusCode =426goog.abstractMethod;427428429/**430* A request header to indicate to the server the messaging protocol431* each HTTP message is speaking.432*433* @type {string}434*/435goog.net.WebChannel.X_CLIENT_PROTOCOL = 'X-Client-Protocol';436437438/**439* The value for x-client-protocol when the messaging protocol is WebChannel.440*441* @type {string}442*/443goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL = 'webchannel';444445446/**447* A response header for the server to signal the wire-protocol that448* the browser establishes with the server (or proxy), e.g. "spdy" (aka http/2)449* "quic". This information avoids the need to use private APIs to decide if450* HTTP requests are multiplexed etc.451*452* @type {string}453*/454goog.net.WebChannel.X_CLIENT_WIRE_PROTOCOL = 'X-Client-Wire-Protocol';455456457/**458* A response header for the server to send back the HTTP session id as part of459* the initial handshake. The value of the HTTP session id is opaque to the460* WebChannel protocol.461*462* @type {string}463*/464goog.net.WebChannel.X_HTTP_SESSION_ID = 'X-HTTP-Session-Id';465466467