Skip to content
A simple and transparent RPC module for Lua.
Lua
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
rockspecs
tango ssl patch by aaron b. applied.
COPYRIGHT MIT copyright added
README.md try to include all clients and servers in tango.lua
tango.lua
test.lua run ssl test only if ssl is available
test_client.lua
test_server.cert
test_server.key
test_server.lua
test_ssl_config.lua ssl patch by aaron b. applied.

README.md

About

tango is a small, simple and customizable RPC (remote procedure call) module for Lua.

Its main features are:

  • a generic transparent proxy for call invocations
  • support of remote objects (tables with functions, userdata etc, see tango.ref)
  • a generic dispatch routine for servers
  • several server implementations for different protocols, message formats and event/io frameworks, further called backends
  • several client implementations for different protocols and message formats

Backends included

Tutorial (copas_socket server + socket client)

Greetings!

The greet server code

-- load tango module
local tango = require'tango'
-- define a nice greeting function
greet = function(...)
          print(...)
        end 
-- start listening for client connections        
tango.server.copas_socket.loop{
  port = 12345
}

The client code calling the remote server function greet

-- load tango module
local tango = require'tango'
-- connect to server
local con = tango.client.socket.connect{
   address = 'localhost',
   port = 12345
}
-- call the remote greeting function
con.greet('Hello','Horst')

Access anything?

Since the server exposes the global table _G per default, the client may even directly call print,let the server sleep a bit remotely (os.execute) or calc some stuff (math.sqrt).

-- variable argument count is supported
con.print('I','call','print','myself')
-- any function or variable in the server's _G can be accessed by default        
con.os.execute('sleep 1')
con.math.sqrt(4)

One can limit the server exposed functions by specifying a functab like this (to expose only methods of he math table/module):

local tango = require'tango'
-- just pass a table to the functab to limit the access to this table
tango.server.copas_socket.loop{
  port = 12345,
  functab = math
}

As the global table _G is not available any more, the client can only call methods from the math module:

con.sqrt(4)

Remote Variables

Sometimes you need to get some data from the server, as enumaration-like-constants for instance. Instead of creating a mess of remote getters and setters, just treat the value of interest as a function...

Let's read the remote table friends from the server

local tango = require'tango'
-- connect to server as usual
local con = tango.client.socket.connect()
-- friends is a remote table but could be of any other type
local friends = con.friends()

To change the servers state, just pass the new value as argument:

local tango = require'tango'
local con = tango.client.socket.connect()
-- read the remote variable
local friends = con.friends()
-- modify it 
table.insert(friends,'Horst')
-- and write back the new value
client.friends(friends)

If you are worried about security concerns, just do not allow read and/or write access:

local tango = require'tango'
-- write_access and read_access can be set independently
-- accessing variables from the client side will now cause errors.
tango.server.copas_socket.loop{
  write_access = false,
  read_access = false
}

Using classes/tables/objects remotely (tango.ref)

Even if Lua does not come with a class model, semi-object-oriented programming is broadly used via the semicolon operator, e.g.:

-- assume you open a pipe locally
local p = io.popen('ls')
-- and read some stuff from it, ... note the : operator
local line = p:read('*l')
...
p:close()

To allow such construct remotely via tango, one has to use the tango.ref:

local con = tango.client.socket.connect()
-- pass in the remote function and all arguments required (optionally)
local p = tango.ref(con.io.popen,'ls')
-- now proceed as if p was a local object
local line = p:read('*l')
...
p:close()
-- unref it locally to let the server release it
tango.unref(p)

This may seem a bit awkward, but it is certainly less hassle, then writing non-object-oriented counterparts on the server side.

Tests

You can run test by the following sh call in the project root directory:

  ./test.lua

tango does not need to be installed.

Client/Server compatibilities

tango.client.sockettango.client.zmq
tango.server.copas_socketX
tango.server.ev_socketX
tango.server.zmqX

Serialization

tango provides a default (lua-only) table serialization which should meet most common use cases.

Anyhow, the table serialization is neither exceedingly fast nor compact in output or memory consumption. If this is a problem for your application, you can customize the serialization by assigning your serialize/unserialize methods to the clients and servers respectively.

Socket client with customized serialization:

local tango = require'tango'
local cjson = require'cjson'
-- set serialization on the client side
local con = tango.client.socket.connect{
   serialize = cjson.encode,
   unserialize = cjson.decode
}

Copas socket server with customized serialization:

local tango = require'tango'
local cjson = require'cjson'
-- set serialization on the server side
tango.server.copas_socket.loop{
   serialize = cjson.encode,
   unserialize = cjson.decode
}

Some alternatives are:

Requirements

The requirements depend on the desired i/o backend, see the corresponding rockspecs for details.

Installation

With LuaRocks: Directly from the its repository:

 $ sudo luarocks install tango-copas

or tango-complete, which requires lua-zmq and lua-ev (and the corresponding C-libs:

 $ sudo luarocks install tango-complete

or a specific rock from

 $ sudo luarocks install https://raw.github.com/lipp/tango/master/rockspecs/SPECIFIC_ROCKSPEC

Note: luarocks must be >= 2.0.4.1 and requires luasec for doing https requests!

 $ sudo apt-get install libssl-dev
 $ sudo luarocks install luasec
Something went wrong with that request. Please try again.