Portal has reached its End of Life and is no longer maintained! Use Use Cettia. ×

Getting started

The Portal is a concise, lightweight and feature-rich JavaScript library for real-time web application development.


Install

As browser client

Download portal.js the way you want.

Though there may be delays between a release and its availability, portal.js is available in the following ways

Then load it by using either script tag or AMD loader.

Script tag

<script src="/portal/portal.min.js"></script>
<script>
portal.open("/test");
</script>

AMD loader

require(["portal"], function(portal) {
    portal.open("/test");
});

As Node.js client

portal.js is available on npm under the name of portal-client. There are differences in many ways between browser and Node.js. Because browser is first runtime engine of portal.js, you should check if there is note for Node.js browsing docs.

Add portal-client to your package.json and install the dependencies. If you are on Windows, you may have trouble in installing Contextify. See a installation guide from jsdom.

npm install

Then load it as a Node.js module.

var portal = require("portal-client");
portal.open("http://localhost:8080/test");

Prepare server

Officially the following portal server is available:

Or you can write your own server easier than expected. See writing server. If you just want to try out portal, you can use a test server written only to run test suite. Follow instructions in README.


Play

It’s time to play.

Realtime event channel

Socket provided by portal is an realtime event channel between portal client and server. Server and client can send and receives events to each other.

portal.open("/portal").on({
    // Pseudo event
    connecting: function() {}, // The selected transport starts connecting to the server
    waiting: function(delay, attempts) {}, // The socket waits out the reconnection delay
    // Network event
    open: function() {}, // The connection is established successfully and communication is possible
    close: function(reason) {}, // The connection has been closed or could not be opened
    // Message event
    message: function(data) {}, // Receive an event whose name is message sent by the server
    event: function(data) {} // Receive an event whose name is event sent by the server
})
.send("greeting", "Hi"); // Send an event whose name is 'greeting' and data is 'Hi' to the server

Socket on Web for All

Considering the real world, many coporate proxies, firewalls, antivirus softwares and cloud application platforms block WebSocket and some HTTP transports or servers can’t detect disconnection or close connection.

portal.open("/portal", {
    heartbeat: true,
    notifyAbort: true,
    prepare: function(connect, cancel, options) {
        // Assume that the server returns the best transports for client
        // Transport negotiation or its guide will be introduced in later 
        $.ajax("/portal/negotiation").done(function(transports) {
            // Modify transport set and connects to the server
            options.transports = trnasports;
            connect();
        });
    }
});

Connection sharing

It’s common case that user opens multiple tabs of same website and each tab have its persistent connection like portal. In the case of a web portal consisting of many portlets, if portlet has a persistent connection, it can’t send any request, receive and display anything in violation of the simultaneous connection limit. By sharing a connection, it can be avoided.

// Sockets using shared connection are considered as a single client to the server
// More extended options will be provided later  
portal.open("/portal", {sharing: true});

Remote Procedure Call (RPC)

Socket can play a role of RPC client. Nothing new to traditional Ajax, but comparing to Ajax, WebSocket can reduce unnecessary traffic and the result can be shared by multiple tabs and windows. Building a web application with portal is a good way to create a economical webapp.

portal.open("/portal")
// If the server requests
.on("user:stat", function(data, reply) {
    // The client can respond with data
    reply(user.stat);
})
// If the client requests
.send("account:find", {id: "flowersinthesand"}, function(account) {
    // The server can respond with data
    console.log(account);
});

Customization

For some reason, you may want to or have to check authorization, perform handshake, handle low-level payload, build URL in REST format, use server-generated socket id and customize everything. Various options support to do that.

portal.open("/portal", {
    // Prepare something before connecting
    prepare: function(connect, cancel, options) {},
    // Convert raw string sent by the server to event object
    inbound: function(data) {},
    // Convert event object to raw string to be sent to the server
    outbound: function(event) {},
    // Build URL to be used by socket
    urlBuilder: function(url, params, when) {},
    // Generate a socket id
    idGenerator: function() {},
    // Determine reconnection delay
    reconnect: function(lastDelay, attempts) {},
    // Modify URL for XDomainRequest
    xdrURL: function(url) {},
    // Parse stream response and find stringified event
    streamParser: function(chunk) {}
});