Skip to content

Latest commit

 

History

History
451 lines (337 loc) · 12.4 KB

index.rst

File metadata and controls

451 lines (337 loc) · 12.4 KB

Hydna2 documentation

Transports

Hydna supports the following transports:

  • HTTP
  • WebSocket
  • EventSource

HTTP

Send POST, GET, PUT or DELETE requests:

curl -d test=fest http://127.0.0.1:8070/test/

Triggers the following handlers:

  • onrequest

WebSocket

Connect with WebSocket:

var ws = new WebSocket("ws://127.0.0.1:8070/test/");

ws.onmessage = function(event) {
    console.log(event);
};

Triggers the following handlers:

  • onopen
  • ondata
  • onclose

EventSource

Connect with EventSource:

var es = new EventSource("http://127.0.0.1:8070/test/");

es.onmessage = function(event) {
    console.log(event);
};

Triggers the following handlers:

  • onopen
  • onclose

Manifest

The manifest is a JSON document responsible for routing events to event handlers.

Example (current syntax):

{
    "channels": [
        {
            "path": "/chat",
            "source": "function onopen(event) { event.accept(); }"
        },
        {
            "path": "/ticker",
            "file": "ticker.js"
        }
    ],
    "ticks": [
        {
            "path": "/ticker",
            "interval": 5000,
            "identifier": "test-tick"
        }
    ]
}

Example (proposed new syntax):

{
    "handlers": [
        {
            "path": "/chat",
            "source": "function onopen(event) { event.accept(); }"
        },
        {
            "path": "/ticker",
            "file": "ticker.js"
        }
    ],
    "agents": [
        {
            "type": "tick",
            "path": "/ticker",
            "settings": {
                "interval": 5000,
                "identifier": "test-tick"
            }
        }
    ]
}

Event handlers

onopen(event)

Triggered when a client attempts to connect to a path. The event object contains the following:

Attributes Description
domain Name of the current domain (string)
ref Unique reference of the connected client (string)
ip IP address of the connected client (string)

headers

An Object containing all headers in the upgrade request (object)

subprotocols A list containing requested sub-protocols (Array)
bindings Any bindings extracted from the path (object)
path The current path (string)
querystring The raw querystring (string)
transport Name of the transport (http or ws) (string)

secure

Booleand dictating whether the connection is encrypted (boolean)

setCookie(value) Set the cookie of the upgrade response (function)

accept([protocol])

Accept connection to open the path with optional sub protocol. Method accept only allows one protocol. An error will be throwed if protocol was not requsted by connection (function)

reject() Reject the request to open the path (function)

Paths that do not link to a behavior that defines a onopen-handler will automatically accept connections. Paths that do define the handler will reject all requests unless exclicitly allowed with a call to event.accept().

Example (current syntax):

function onopen(event) {
    event.accept();
}

Example (Get and set cookie):

function onopen(event) {
    if (event.headers.cookie.startsWith("last-visit=")) {
        const lastVisit = event.headers.cookie.substr(11);
        console.log(`Last visit ${last-visit}`);
    }
    const now = Date.now();
    event.setCookie("last-visit=" + now);
    event.accept();
}

Example (accept with a sub-protocol):

function onopen(event) {
    if (event.subprotocols.includes("admin") &&
        event.querystring === Domain.env("admin-password")) {
        // Accept an admin connection if password is matching.
        event.accept("admin");
    } else if (event.subprotocols.includes("monitor")) {
        // Accept a monitor connection, no password needed.
        event.accept("monitor");
    } else {
        // Did not match any of our sub-protocols
        event.reject();
    }
}

function onmessage(event) {
    if (event.subprotocol === "admin") {
        // Do stuff with an admin connection
    } else if (event.subprotocol === "monitor") {
        // Do stuff with a monitor connection
    }
}

onclose(event)

Triggered when a client closes a path or is disconnected. The event object contains the following:

Attribute Description
domain Name of the current domain (string)
ref Unique reference of the connected client (string)
bindings Any bindings extracted from the path (object)
path The current path (string)

subprotocol

The accepted subprotocol of connection, or empty string if not set when connection was accepted (string)

reason An optional reason for the event (string)

Example (current syntax):

function onclose(event) {
    console.log(event);
}

ondata(event)

Triggered when a client sends data to a path. The event object contains the following:

Attribute Description
domain Name of the current domain (string)
ref Unique reference of the connected client (string)
ip IP address of the connected client (string)
bindings Any bindings extracted from the path (object)
path The current path (string)
querystring The raw querystring (string)
transport Name of the transport (http or ws) (string)

secure

Booleand dictating whether the connection is encrypted (boolean)

subprotocol

The accepted subprotocol of connection, or empty string if not set when connection was accepted (string)

data The data sent (string)

relay()

Automaically relay the data to all clients connected to the path (function)

Paths that do not link to a behavior that defines a ondata-handler will automatically relay the data to all connected clients. Data sent to paths that do define the handler will not be sent unless it is explicitly sent with either event.relay() or Channel.send(path, msg).

Example (current syntax):

function ondata(event) {
    Channel.send(event.path, event.data);
}

Or the same effect but more efficient:

function ondata(event) {
    event.relay();
}

onrequest(request)

Triggered when a HTTP request is made.

Attribute Description
domain Name of the current domain (string)
ref Unique reference of the connected client (string)
ip IP address of the connected client (string)
bindings Any bindings extracted from the path (object)
path The current path (string)
querystring The raw querystring (string)
transport Name of the transport (http or ws) (string)

secure

Booleand dictating whether the connection is encrypted (boolean)

data The data sent (string)
resp(body) Respond to the request.

Example:

function onrequest(req) {
    req.resp("Hello world");
}

onevent(request)

Triggered when an event is dispatched on a path.

Attribute Description
domain Name of the current domain (string)
bindings Any bindings extracted from the path (object)
path The current path (string)
querystring The raw querystring (string)
transport Name of the transport (http or ws) (string)

secure

Booleand dictating whether the connection is encrypted (boolean)

data The data sent (string)
resp() Respond to the request.

Agents

Agents are long-lived processes that trigger events on paths.

Tick agent

The tick-agent triggers an event on a path on interval. The event object has the following attributes:

Attribute Description
domain Name of the current domain (string)
bindings Any bindings extracted from the path (object)
path The current path (string)
querystring The raw querystring (string)
type Type of agent ('tick')
identifier Unique identifier of the agent (string)
interval Interval at which the agent is running

Example handler:

function onevent(event) {
    const url = 'http://quotes.stormconsultancy.co.uk/random.json';
    http.get(url).then(function(resp) {
        const quote = JSON.parse(resp.body);
        const msg = `[quote] "${quote.quote}" by ${quote.author}\n`;
        Channel.send(event.path, msg);
    });
}

API

Channel

An api to interact with Hydna channels. All functions in this module return a Promise-instance.

Channel.send(path, data)

Send data to a channel.

Example:

Channel.send('/world', 'Hello!');

Client

Rename to "Connection"?

An api to interact with clients/connections. All functions in this module return a Promise-instance.

Client.send(ref, message)

Send a message to a specific client identified by ref.

Example:

Client.send(event.ref, "Welcome!");

Http

An api to make HTTP requests. All functions in this module return a Promise-instance.

Http.get(url, [options])

Make a HTTP GET request to url.

Example:

Http.get('http://httpbin.org/get?test=fest', {
    headers: { 'Content-Type': 'application/json' },
    payload: {test: 'fest'}
}).then(function(resp) {
    console.log(resp);
}).catch(function(error) {
    console.log(error);
});

Http.post(url, [options])

Make a HTTP POST request to url.

Example:

Http.post('http://httpbin.org/post', {
    payload : 'hello'
}).then(function(data) {
    console.log(data);
}).catch(function(error) {
    console.log(error);
});

Http.put(url, [options])

Make a HTTP PUT request to url.

Example:

Http.put('http://httpbin.org/put', {
    payload : 'hello'
}).then(function(data) {
    console.log(data);
}).catch(function(error) {
    console.log(error);
});

Http.delete(url, [options])

Make a HTTP DELETE request to url.

Example:

Http.delete('http://httpbin.org/delete', {
    payload : 'hello'
}).then(function(data) {
    console.log(data);
}).catch(function(error) {
    console.log(error);
});