Host SubEtha clients and messages
version 0.0.2-alpha by Bemi Faison
SubEtha-Bridge (or Bridge) is a supporting library within the SubEtha messaging architecture. A bridge routes messages between clients on the same bridge, and relays messages between bridges on the same "network" - i.e., the channel and url origin.
Bridges primarily implement the SubEtha protocol for communicating with Clients, and require zero configuration. Some security, monitoring and bootstrapping options are available.
Note: Please see the SubEtha project page, for important background information, plus development, implementation, and security considerations.
The Bridge module runs in a web page that is separate from your application code. Bridges are loaded in iframes by the SubEtha-Client library, as needed.
Hosting your own Bridge
Implementing your own Bridge is a simple matter of hosting a static web page. The web page should do little more than load the Bridge module, except for however you choose to customize it's behavior.
Below demonstrates a complete bridge implementation that you could host on any server.
Connecting to your Bridge
If the url to your bridge were
http://my.site.com/bridge.html, clients could then connect to it in their applications, like so:
// open a channel on your bridgevar myAppClient = ;myAppClient;
If applications plan to use several clients with your bridge, they might set and use a convenient alias, instead.
// define an alias to your bridge urlSubethaurlsmybridge = 'my.site.com/bridge.html';// open a channel using an aliasvar myAppClient = ;myAppClient;
Bootstrapping Asynchronous Bridges
The Bridge module has a bootstrap process that involves capturing the first message event - sent via postMessage, from the SubEtha-Client in the parent window. It is strongly recommended that you load the Bridge module synchronously (via a SCRIPT tag, or otherwise, before the DOM is ready). If you do load the Bridge module asynchronously, you must capture the first message event and pass it's data, manually.
Below demonstrates loading the Bridge module with require.js and capturing the first message event. It ensures the bridge is only initialized when both it and the event are available, regardless of load order.
Note: The above leaves
scripts/config to configure the "subetha-bridge" module path and dependencies.
Handling Client Requests
Bridges handle two types of client requests: authentication requests, and message-relay requests. These requests are accepted by default, such that any client may join a channel and send any message.
To handle requests manually, simply subscribe to the "auth" and/or "relay" events. Callbacks receive a request object, which represents the suspended state of a request. Requests may be answered asynchronously, but can only be answered once.
// handle client authentication requestsSBridge;// handle message relay requestsSBridge;
To answer a request invoke it's
#ignore() method. The first call to any method will return
true, but once handled these methods (do nothing and) return
Note: The same request object is passed to all callbacks. If using multiple callbacks for an event, ensure only - and, at least - one handles the request object.
To restore the default behavior, remove all subscriptions to the given event type. Invoke
#off(), passing only the event type.
// re-enable default handling of authentication requestsSBridge;// re-enable default handling of message-relay requestsSBridge;
Authentication-requests may be handled in any order, and are stored in the
SBridge.pendingAuths hash until processed. If your bridge employs some form of authorization, requests expose any credentials given by the client, in a
.credentials array. (An empty array, means no credentials were sent.)
Message-relay requests can only be handled in the order they are received. When a request is suspended, it is passed to subscribers of the "relay" event, and set in the
It's important to consider latency, when processing a relay request. More message-relay requests will pile up as you perform your logic, which can reduce perceived performance of your bridge. Try to handle message-relay requests immediately, instead of asynchronously.
Below, demonstrates logic that prevents broadcast messages - messages without a recipient.
Monitoring Bridge Activity
The following events are available for you to observe, on the Bridge module directly.
- initialize Fired when the Bridge is awaiting client messages.
- join Fired when a client has joined the network. The arriving client is passed to callbacks.
- drop Fired when a client has exited the network. The departed client is passed to callbacks.
- message Fired when a message is relayed. The delivered message is passed to callbacks.
Note: Unlike the SubEtha-Client module, Bridge events are not prefixed.
Below demonstrates logic that observes when a new client has been authenticated by the current bridge.
Below is reference documentation for the SubEtha-Bridge module.
A singleton, representing the client authorization and message routing logic for the window.
The bridge fires the following events.
- relay - Triggered before a message is relayed. Subscribing to this event requires responding to the relay-request.
request- An object representing the suspended request.
- auth - Triggered when a client attempts to use this bridge to join the network.
request- An object representing the suspended request.
- join - Triggered when a client joins the network.
client- A reference to the client that recently joined the network.
- drop - Triggered when a client leaves the network.
client- A reference to the client that recently left the network.
- message - Triggered when a client message is relayed.
msg- The message relayed on the network.
End handling network clients and messages. You can not reuse the bridge once destroyed.
Triggers callbacks, subscribed to this event.
SBridge.fire(event [, args, ... ]);
- event: (string) The event to trigger.
- args: (Mix) Remaining arguments that should be passed to all attached callbacks.
Begin handling network clients and messages.
- token: (string) A serialized string of parameters needed to bootstrap the SBridge singleton.
This method simply exits if the bridge has already been initialized.
Unsubscribe callback(s) from an event. When invoked with no arguments, all subscriptions are removed.
SBridge.off([event [, callback [, scope]]]);
- event: (string) The event to unsubscribe. When omitted, all event subscribers are removed.
- callback: (function) The callback to detach from this event. When omitted, all callbacks are detached from this event.
- scope: (object) Specifies detaching the given callback that is also scoped to the given object. Do not use, unless you attached a callback with a particular scope.
Subscribe a callback to an event.
SBridge.on(event, callback [, scope]);
- event: (string) An arbitrary event name.
- callback: (function) A callback to invoke when the event is fires.
- scope: (object) An object to scope the callback invocation. By default, this is the EventEmitter instance.
Indicates when the bridge is incompatible with the runtime environment.
A hash to uniquely identify this bridge.
The name of the network, as prescribed by the bootstrap token.
The last pending message relay request object. If no relay is pending, the value is
Hash of pending authorization request objects. Keys are of clients waiting to gain access.
The SemVer compatible version of the SubEtha protocol supported by this module.
The SemVer compatible version of this module.
If SubEtha-Bridge isn't compatible with your favorite runtime, please file an issue or pull-request (preferred).
SubEtha-Bridge depends on the following modules:
SubEtha-Bridge also uses the following ECMAScript 5 and HTML 5 features:
You will need to implement shims for these browser features in unsupported environments. Note however that postMessage and localStorage shims will only allow this module to run without errors, not work as expected.
<SCRIPT> tag to load the subetha-bridge.min.js file in your web page. The file includes all module dependencies, for your convenience. Doing so, adds
SBridge to the global scope.
Note: The minified file was compressed by Closure Compiler.
npm install subetha-bridge
component install bemson/subetha-bridge
bower install subetha-bridge
Assuming you have a require.js compatible loader, configure an alias for the SubEtha-Bridge module (the term "subetha-bridge" is recommended, for consistency). The subetha-bridge module exports a module namespace.
Then require and use the module in your application code:
Warning: Do not load the minified file via AMD, since it includes modular dependencies that themselves export modules. Use AMD optimizers like r.js, in order to roll-up your dependency tree.
Note: When loaded asynchronously, you must manually bootstrap this module. (See the usage section for more details.)
SubEtha-Bridge is available under the terms of the Apache-License.
Copyright 2014, Bemi Faison