0.1.0 • Published 10 years ago

invoke-server v0.1.0

Weekly downloads
4
License
-
Repository
github
Last release
10 years ago

Invoke

Invoke is an exeprimental http-server and a browser library dramatically simplifying the client-server communication down to a function call. That is, literally: declare a function on a server, then directly use it in a browser:

Server (Node.js):

var invoke = require('invoke-server');

// starting a server on port 1337
var server = new invoke.Server(1337);

// a set of functions to be available from the browser
server.expose({
    // prints a message on the server console
    log: console.log,
                  
    // provides the content of that file
    readThatFile: function(cb) {
        cb(require("fs").readFileSync('thatFile.txt').toString());
    }
});

Client (web-browser):

<script type="text/javascript" src="invoke.js"></script>
// connecting to the server
var host = new invoke.Host('http://127.0.0.1:1377/');

var start = function() {
    // functions exposed by the server are available at host.api

    // printing a message on the SERVER console
    host.api.log('hello');

    // reading the content of that file
    host.api.readThatFile(function(content) {
        // printing the content on the browser console
        console.log(content);
    });
}


host.whenConnected(start);

What's happening?

A list of exposed functions names is provided to the browser upon connection. For each exposed function name, the browser library creates a special wrapper. Upon being called, the wrapper serializes the provided arguments into a JSON-string, and performs an ordinary request to the server. The server in turn rebuilds a list of arguments, and calls the actual function. If that function then executes a callback, a responce is sent in the opposite direction, which finally leads to an actual callback execution (preserved in advance before sending the request).

The messaging mechanism reused beyond the remote function invocation introduces some natural limitations for the exposed functions and their usage (nevertheless the most common use-cases are still straightforward):

  • Exposed function arguments may only be either simple objects (which are then serialized and sent within a request), or callbacks (which are preserved and replaced with special identifiers before sending). Custom object instance may not be used as an argument.

  • A callback can not be executed several times, a responce is sent upon the first invocation.

  • If several callbacks are provided, only one of them may be called.

  • Returned value of an exposed function is ignored, result should be provided to a callback instead.

Setting-up

Server (Node.js)

Install invoke-server using npm:

$ npm install invoke-server

and then load the library:

var invoke = require('invoke-server');

Optionally you may load the script from the distribution:

var invoke = require('path/to/invoke-server.js');

Then create a script which starts the server and exposes the needed functions:

var invoke = require('invoke-server');

var server = new invoke.Server(1337);

server.expose({
    doThis: function() {
        // do this
        ...
    },

    doThat: function() {
        // do whatever else
        ...
    }
});

Server object constructor argument is an optional port number (defaults to 80). The mentioned expose() method takes an object containing a list of functions to be provided to the browser.

Finally save the file and launch it using Node.js:

$ node server.js

In order to close the server programmatically, use close() method. The provided callback is invoked when connection is closed:

server.close(cb);
Client (browser)

Download the distribution, unpack it and load the invoke.js in a preferrable way. That is an UMD module, thus for instance it may simply be loaded as a plain JavaScript file using the <script> tag:

<script type="text/javascript" src="invoke/invoke.js"></script>

After loading the library, the invoke object is created.

To connect to a host running an invoke-server, create a Host instance:

var host = new invoke.Host('http://127.0.0.1:1377/');

var start = function() {
    // using functions provided by the server
    host.api.doThis();
    host.api.doThat();
}


host.whenConnected(start);

The whenConnected() method subscribes a listener to the connection event. After the listener is executed, a set of function exposed by the server is directly available at the api property of the host object. You may subscribe a listener using whenConnected() function even after the server is already connected (in this case the listener is invoked immediately).

In addition to whenConnected() method, the Host object also provides the whenFailed() subscriber to an event triggered if the connection to the server could not be established. Just like as for whenConnected() method, the whenFailed() may also be used several times or even after the event has actually been fired.

Normally the exposed function takes a callback (or sereval callbacks) in order to report the result. If no callbacks are provided upon the function call, the responce is sent immediately. Otherwise the response is only sent when an exposed function invokes a callback.

If a problem happened during the exposed function execution, the error is sent as a responce and provided as an argument to the last callback on the arguments list (which is assumed to be the failure callback).

--

You can find me on twitter: https://twitter.com/asvd0

Also check out some of my projects on github (ordered by my impression of their significance):

Helios Kernel: isomorphic javascript module loader

Jailed: sandboxed execution of untrusted code

Lighttest: isomorphic unit-testing library