hakobiya

command module
v0.0.0-...-dec14df Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2014 License: BSD-2-Clause Imports: 15 Imported by: 0

README

Hakobiya

The real-time helper. Remote data binding for Angular.js using Websockets.

Do you have an old app using AJAX for 'soft' real time and need a really real-time bridge? Do you have an app that just needs to push around some data from client to client and you don't want to write a whole new server? Hakobiya could be the answer.

A Hakobiya server has one or more channel templates. Channels have names, and the type of channel is specified by the first letter of the name. You can configure each type of channel to store variables (data for each user), computed values of user variables (magic variables), and client to client communication slots called wires. Additionally, you can chose to expose system variables to clients, such as the number of clients listening in a particular channel. You can then bind any of these values to Javascript variables and everything will be automatically synchronized.

Hakobiya has an HTTP API that lets you set values and send messages in any channel, so you can have something else handle the logic and let Hakobiya take care of updating your users.

Configuration

The default config file is config.toml. You can specify a different file with the -config flag:

hakobiya -config /some/dir/hakobiya.toml
Types

Variable definitions can take a type, which may be any of the following:

  • "bool"
  • "int"
  • "float"
  • "string"
  • "object"
  • "any" (or blank)

Server config

[server]

General server configuration.

Name Type Required? Default Description
name string optional "Hakobiya" Server name
bind string optional ":8080" Bind address: [host]:port
path string optional "/hakobiya" Path for Websocket server
Example

Sets up a server called Chat Helper at ws://0.0.0.0/chat.

[server]
name = "Chat Helper"
bind = ":80"
path = "/chat"

API config

[api]

The API lets you send messages to clients and set and get values via HTTP.

Name Type Required? Default Description
enabled bool optional false Enable the API?
path string optional "/api" API root path
key string optional Secret key
Example

Enables the API at the default path with a secret key of "turtles".

[api]
enabled = true
key = "turtles"

Channel config

[[channel]]

Defines channels (note the double brackets). Channels are distinguished by their first letter (the prefix value) and are created on-the-fly when joined by a client. Any string after the prefix is OK for a channel name.

Name Type Required? Default Description
prefix char required Distinguishing prefix
expose string[] optional [] System variables to expose
Example

Defines a channel with a prefix of "c" that exposes the system variable $listeners to clients. Any channel with a name starting with "c" will be handled by this: c123, cTest, etc.

[[channel]]
prefix = "c"
expose = ["$listeners"]
User variables (%var)

[channel.var.(variable name)]

Defines a per-user value. You can use these values when computing magic variables.

Name Type Required? Default Description
type type optional "any" The type of this variable
default * optional Default value for this variable
Example

Defines a string user variable called %username, and a boolean variable called %typing.

[channel.var.username]
	type = "string"
[channel.var.typing]
    type = "bool"
Magic, computed values (&var)

[channel.magic.(variable name)]

Magic variables are computed values based on user variables.

Name Type Required? Default Description
src string required Source variable to base calculations on
func string required Name of the function to reduce the values, see the Magic docs
Example

Defines a magic variable called &typers that counts the number of users who have %typing set to true.

[channel.magic.typers]
	src  = "%typing"
	func = "count"
Wire (=var)

[channel.wire.(variable name)]

Wires let clients send and receive messages to all other clients on the channel. You can optionally specify rules to rewrite incoming messages, combining them with other variables or literal text. You can make a wire read-only, which prevents clients from sending messages to it but allows you to send messages via the HTTP API.

Name Type Required? Default Description
type type optional "any" Input type
readonly bool optional "false" If set to true, only the HTTP API can send messages
Wire rewrite rules

[channel.wire.(variable name).rewrite]

A table used for compositing input and other variables or literal text. The keys are the names for the new JSON object fields, the values are variable names (with sigil) to substitute (such as "%name"), "$input" to specify the input, or text literals with a leading single quote (like "'hello").

Example

Defines a wire called =chat that takes a string as input and rewrites it as an object containing the input and the username of the sender.

[channel.wire.chat] 
	type = "string"
	[channel.wire.chat.rewrite]
		sender = "%username" 
		msg = "$input"

A client could send a message like "hello world" to the wire, which would then send a JSON object like this to all clients on the channel:

{
    "sender": "LlamaGuy",
    "msg": "hello world"
}

Hakobiya.js

Angular.js module. Include the hakobiya module in your project and use Hakobiya.bind() to do your dirty work.

function ChatCtrl($scope, Hakobiya) {
	$scope.channel = "c12345";
	$scope.name = "Guest";
	$scope.chat = undefined;
	$scope.users = 0;

	Hakobiya.bind($scope, "channel",
	{
		"name": "%username",
		"chat": "=chat",
		"users": "$listeners",
	});
}

User variables have two-way binding. System variables have one-way binding. Wires are a special array: they have a .send() method to send data.

You can manually listen for changes to any of these variables like so:

$scope.$on("c12345.=chat", function(evt, value) {
    console.log(value);
});

Event names have the format of (channel).(variable).

Also, don't forget to connect.

myModule.run(function (Hakobiya) {
				Hakobiya.connect("ws://0.0.0.0/chat");
			});

HTTP API

All API methods are POST only for now.

Keys

You can set a secret key in API section of the config file. You must then send this key to every request. You can add it to the JSON of your request as "key":"abc" or in the URL like ?key=abc.

Get

/api/(channel name)/get

Expects JSON like:

{
    "var": "%name", // the variable you want
    "for": "_AsbxHShw", // optional, some connection's user ID
    "key": "123" // optional, you can put it in the URL or disable it
}

Set

/api/(channel name)/set

Expects JSON like:

{
    "var": "=chat", // desired variable
    "value": "Hello from the API!", // desired value, here a string but it could be anything
    // this next bit is all optional, and useful for wires with rewrites
    // it lets you overwrite any parts of your potentially transformed message
    // and let's you "spoof" values that would otherwise be taken from users
    // or add extra server info from the server
    "overwrite": {
        "name": "SERVER"
    }
}

Response

{
	"code": 1 // reponse code: 1 = OK, 0 = nothing happened, -1 = error
	"msg": "something happened", // error message, etc
	"value": "..." // value you requested or other pertitent data
}

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL