Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b01bdd4
chore(wish/cpp): style fixes
nlattice May 27, 2026
a33ac92
feat(wish/cpp): clean up logs
nlattice May 27, 2026
ff980f3
feat(wish/cpp): use `picohttpparser` for parsing headers
nlattice May 27, 2026
50789ae
chore(wish/cpp): pin down deps
nlattice May 27, 2026
05b99d4
chore(wish/cpp): stop using `main`/`master` in deps
nlattice May 27, 2026
1a0bc32
fix(wish/cpp): fix the `nghttp2` (static lib) dep identifier
nlattice May 27, 2026
e146c94
chore(wish/cpp): clean up `CMakeLists.txt`
nlattice May 27, 2026
72fcdb0
chore(wish/cpp): reorganize `cmake` targets
nlattice May 27, 2026
a817826
chore(wish/cpp): clean up `cmake` options for `nghttp2`
nlattice May 27, 2026
d9bc34c
chore(wish/cpp): revise the name of the `wslay` patch file
nlattice May 27, 2026
eabea19
fix(wish/cpp): add missing error handling
nlattice May 27, 2026
cc34984
fix(wish/cpp): tolerate TLS dirty shutdown
nlattice May 27, 2026
b809057
fix(wish/cpp): clean up `SSL` object where needed
nlattice May 27, 2026
a030b81
chore(wish/cpp): unify the way to handle return values
nlattice May 27, 2026
e037f88
fix(wish/cpp): make the handshake handler reject unsupported/not-yet-…
nlattice May 27, 2026
8f888de
fix(wish/cpp): revise the life cycle of classes
nlattice May 27, 2026
59866a8
fix(wish/cpp): convert `LOG`s to `VLOG`s
nlattice May 27, 2026
dcd074c
fix(wish/cpp): fix the clean up order in the destructors
nlattice May 27, 2026
045cd82
feat(wish/cpp): inject `event_base` than creating one on the library …
nlattice May 27, 2026
ff90d43
fix(wish/cpp): add missing error handling
nlattice May 27, 2026
066d76b
chore(wish/cpp): clean up comments
nlattice May 27, 2026
e1947b0
chore(wish/cpp): add copyright boilerplate
nlattice May 27, 2026
d71e0af
[webchannel] Add JavaScript client implementation
sampajano Jun 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions webchannel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# WebChannel

WebChannel is a bidirectional communication protocol designed to provide reliable, full-duplex communication channels over HTTP.

This directory is the multi-language home for WebChannel client implementations.

## Directory Structure

- [js/](js/) - JavaScript client implementation (based on Closure Library).
- [imported_src/](js/imported_src/) - Imported source files from Closure Library.
- [objc/](objc/) - (Planned) Objective-C client implementation.

## JavaScript Client (`webchannel/js`)

The JavaScript implementation of the WebChannel client is based on the Google Closure Library.

The raw imported source files are located in `js/imported_src/`.
186 changes: 186 additions & 0 deletions webchannel/js/imported_src/channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/**
* @license
* Copyright The Closure Library Authors.
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview A core interface for WebChannelBase.
*
*/
goog.module('goog.labs.net.webChannel.Channel');
goog.module.declareLegacyNamespace();

const ChannelRequest = goog.requireType('goog.labs.net.webChannel.ChannelRequest');
const ConnectionState = goog.requireType('goog.labs.net.webChannel.ConnectionState');
const Uri = goog.requireType('goog.Uri');
const XhrIo = goog.requireType('goog.net.XhrIo');

/**
* Core interface for WebChannelBase.
*
* @interface
*/
function Channel() {}

/**
* Determines whether to use a secondary domain when the server gives us
* a host prefix. This allows us to work around browser per-domain
* connection limits.
*
* If you need to use secondary domains on different browsers and IE10,
* you have two choices:
* 1) If you only care about browsers that support CORS
* (https://developer.mozilla.org/en-US/docs/HTTP_access_control), you
* can use {@link #setSupportsCrossDomainXhrs} and set the appropriate
* CORS response headers on the server.
* 2) Or, override this method in a subclass, and make sure that those
* browsers use some messaging mechanism that works cross-domain (e.g
* iframes and window.postMessage).
*
* @return {boolean} Whether to use secondary domains.
* @see http://code.google.com/p/closure-library/issues/detail?id=339
*/
Channel.prototype.shouldUseSecondaryDomains = goog.abstractMethod;

/**
* Called when creating an XhrIo object. Override in a subclass if
* you need to customize the behavior, for example to enable the creation of
* XHR's capable of calling a secondary domain. Will also allow calling
* a secondary domain if withCredentials (CORS) is enabled.
* @param {?string} hostPrefix The host prefix, if we need an XhrIo object
* capable of calling a secondary domain.
* @param {boolean=} isStreaming Whether or not fetch/streams are enabled for
* the underlying HTTP request.
* @return {!XhrIo} A new XhrIo object.
*/
Channel.prototype.createXhrIo = goog.abstractMethod;

/**
* Callback from ChannelRequest that indicates a request has completed.
* @param {!ChannelRequest} request
* The request object.
*/
Channel.prototype.onRequestComplete = goog.abstractMethod;

/**
* Returns whether the channel is closed
* @return {boolean} true if the channel is closed.
*/
Channel.prototype.isClosed = goog.abstractMethod;

/**
* Callback from ChannelRequest for when new data is received
* @param {ChannelRequest} request
* The request object.
* @param {string} responseText The text of the response.
*/
Channel.prototype.onRequestData = goog.abstractMethod;

/**
* Callback from ChannelRequest for when the first byte of response body has
* been received. This is needed for detecting buffering proxies.
* @param {!ChannelRequest} request
* The request object.
* @param {string} responseText The text of the response.
*/
Channel.prototype.onFirstByteReceived = goog.abstractMethod;

/**
* Gets whether this channel is currently active. This is used to determine the
* length of time to wait before retrying. This call delegates to the handler.
* @return {boolean} Whether the channel is currently active.
*/
Channel.prototype.isActive = goog.abstractMethod;

/**
* Not needed for testchannel.
*
* Gets the Uri used for the connection that sends data to the server.
* @param {string} path The path on the host.
* @return {Uri} The forward channel URI.
*/
Channel.prototype.getForwardChannelUri = goog.abstractMethod;

/**
* Not needed for testchannel.
*
* Gets the Uri used for the connection that receives data from the server.
* @param {?string} hostPrefix The host prefix.
* @param {string} path The path on the host.
* @return {Uri} The back channel URI.
*/
Channel.prototype.getBackChannelUri = goog.abstractMethod;

/**
* Not needed for testchannel.
*
* Allows the handler to override a host prefix provided by the server. Will
* be called whenever the channel has received such a prefix and is considering
* its use.
* @param {?string} serverHostPrefix The host prefix provided by the server.
* @return {?string} The host prefix the client should use.
*/
Channel.prototype.correctHostPrefix = goog.abstractMethod;

/**
* Not needed for testchannel.
*
* Creates a data Uri applying logic for secondary hostprefix, port
* overrides, and versioning.
* @param {?string} hostPrefix The host prefix.
* @param {string} path The path on the host (may be absolute or relative).
* @param {number=} opt_overridePort Optional override port.
* @return {Uri} The data URI.
*/
Channel.prototype.createDataUri = goog.abstractMethod;

/**
* Not needed for testchannel.
* Gets the result of previous connectivity tests.
*
* @return {!ConnectionState} The connectivity state.
*/
Channel.prototype.getConnectionState = goog.abstractMethod;

/**
* Sets the parameter name for the http session id.
*
* @param {?string} httpSessionIdParam The parameter name for http session id
*/
Channel.prototype.setHttpSessionIdParam = goog.abstractMethod;

/**
* Gets the parameter name for the http session id.
*
* @return {?string} The parameter name for the http session id.
*/
Channel.prototype.getHttpSessionIdParam = goog.abstractMethod;

/**
* Sets the http session id.
*
* @param {string} httpSessionId The http session id
*/
Channel.prototype.setHttpSessionId = goog.abstractMethod;

/**
* Gets the http session id.
*
* @return {?string} The http session id if there is one in effect.
*/
Channel.prototype.getHttpSessionId = goog.abstractMethod;

/**
* Whether or not this channel uses WHATWG Fetch/streams.
*
* @return {boolean} true if use Fetch streams.
*/
Channel.prototype.usesFetchStreams = goog.abstractMethod;

// MOE:begin_strip
// Ensure ES2021 inputs. go/transpile-js
null?.(6_6);
// MOE:end_strip

exports = Channel;
Loading