Socket
Socket
Sign inDemoInstall

architect-agent

Package Overview
Dependencies
0
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    architect-agent

This is the rpc agent for the architect plugin framework


Version published
Weekly downloads
4
decreased by-33.33%
Maintainers
1
Install size
20.4 kB
Created
Weekly downloads
 

Readme

Source

This module is the actual serialization format and protocol for the remoteagent system.

It is transport agnostic so that it can work on any duplex socket. A modified version of msgpack is used as the serialization format when using the binary socket transport (undefined and Buffer types are added). Other transports such as socket.io in the browser can be used.

Encoded on top of the serialzation format is functions and cycles. This almost any basic value can be encoded and sent across the socket.

Since functions can be serialized, rpc using callbacks is natural. Simply pass your callback as an argument and the other side will get a proxy function when it's deserialized. When they call that proxy function, a message will be sent back and your callback will get called with the deserialized arguments (which can include yet another callback). Since the callbacks are executed on their native side, closure variables and all other state is preserved. Callbacks functions may only be called once. The internal reference is deleted after the first call. For functions that are called multiple times, use the named functions map passed into the Agent.

Message Encoding

On top of serializing primitive values and basic data structures, remoteagent- protocol can encode proxy functions and cycles in an object. This is encoded using objects with the $ magic key. Any existing keys that start with $ will be escaped by prefixing an extra $.

Function Encoding

Functions are encoded with the $ key. The value of this object is the unique function index in the local function repository. Function keys integers. An example encoded function can look like {$: 3} where callbacks[3] in the server is the real function.

Cycle Encoding

Sometimes objects have cycles in them. It would be nice if these could be encoded, serialized, and send to the other side intact without blowing up the rpc system. Cycles are encoded with the $ key. The value is the path to the actual value as an array of strings. In this way it works like a file- system symlink. Currently the path is absolute starting at the root of the message. For example. Given the following cyclic object:

var entry = {
  name: "Bob",
  boss: { name: "Steve" }
};
entry.self = entry;
entry.manager = entry.boss;

The following encoded object is generated by the internal freeze function in protocol.serializer().

{
  name: 'Bob',
  boss: { name: 'Steve' },
  self: { $: [] },
  manager: { $: [ 'boss' ] }
}

See that the path [] point to the object itself, and ['boss'] points to the boss property in the root.

Agents

The main public interface is the Agent class. There is typically one of these per network node (process) in a remoteagent mesh. The agent holds the named functions that this node serves to the other nodes.

var Agent = require('architect-agent').Agent;

var agent = new Agent({
	add: function (a, b, callback) {
		callback(a + b);
	}
});

In this example, we created a new agent, gave it the ID "main" and declared that it provides an add function.

Transports

Transports handle internally the serialization of static objects. This can be JSON or msgpack or something else.

Transports must have a .send() property for sending messages to the other side and emit "message" events (or call their onMessage property) whenever a message arrives from the other side. The message is an object not a json string or msgpack buffer. The transport is not responsible for encoding functions and cycles, that is done at a higher level.

When using the built-in socket-transport, messages are framed in the stream using a 4 byte length header (UInt32BE) before every message. This way the receiving end knows how much buffer to allocate and can efficiently scan and deframe the incoming message stream. This also means that the msgpack parser can assume it has the entire message in memory once the message emit from the deframer.

Here is an example networkserver that accepts remoteagent connections over a tcp port. We are assuming the agent variable declared in the sample above.

var net = require('net');
var socketTransport = require('architect-socket-transport');

net.createServer(function (socket) {
	agent.attach(socketTransport(socket), function (client) {
		// Do something with client if it has functions to serve
	});
}).listen(1337);

Then to connect to this, from the client connect to this server.

var net = require('net');
var socketTransport = require('architect-socket-transport');

var Agent = require('architect-agent').Agent;

var agent = new Agent();

var client = net.connect(1337, function () {
	agent.attach(socketTransport(client), function (server) {
		// Use server's exported functions
		server.add(1, 2, function (result) {
			// result should be 3!
		});
	});
});

FAQs

Last updated on 24 Apr 2012

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc