RIO |
Remote Interface for Objects |
1. Introduction
RIO is a http-based protocol I recently (2005) designed.
It is short for
remote interface for objects and is meant as a light-weight, ASCII based RPC protocol which can encode/decode several atomic datatypes (boolean, integer, long, float, double, time, string) as well as complex datatypes like hashtables, arrays and classes.
I have written a tiny test-server in tkscript which I placed under the terms of the BSD license.
Please notice that SDL_net uses blocking socket-writes by default but I guess this does not matter for a test-server :-)
The more formal RIO specs can be found
here.
Currently, this is more a
proof-of-concept implementation. The following things still need to be done:
- Write a TkScript client library
- Write client libraries for JavaScript, ActionScript, ..
- Someone else will have to do this, I am not a web programmer, sorry ;)
2. Examples
The following examples use the example service implementation, see
service.tks.
Writing a service is easy, each
DAO
(data access object) has to be derived from
RIO_Namespace
.
The service description,
DefaultService
, must be derived from
RIO_ServiceProvider
.
The argument/return value en/decoding will automatically be handled by RIO.
module "MDefaultService";
class TestVO {
String
key;
String
value;
}
TestVO vo;
class TestDAO : RIO_Namespace {
getName { return "TestDAO"; }
getProcedures { return
"ap 1"
" create 2 key s value s : TestVO"
;
}
create(String
key, value) { vo.key=key; vo.value=value; return vo; }
}
class DefaultService : RIO_ServiceProvider {
public init() returns boolean {
return RIO_ServiceProvider::init()
&& addClass(TestVO)
&& addNamespace(TestDAO)
;
}
}
The
DefaultService
can then be used to initialize the RIO service:
module Main;
RIO_Server rio_server;
Buffer
rio_xferbuf;
function main() {
if(RIO_Service.Start(new DefaultService))
{
rio_xferbuf.size = RIO.MAX_MSG_SIZE;
if(rio_server.start(8080, 4))
{
while(1)
{
// Wait for activity and process clients
rio_server.process(rio_xferbuf);
rio_server.keepAlive();
SDL.delay(1);
}
}
else
{
die "[---] failed to create server socket. ups.";
}
}
else
{
die "[---] failed to start service.";
}
}
Also see
files/rio.zip which contains the complete example code and RIO toolkit source codes.
2.1. Starting the server
Download the
files/rio.zip source package and type
$ curl -O http://tkscript.de/files/rio.zip
$ unzip rio
$ cd rio
$ tks rio
| |
respectively click
tkx/rio.tkx to start the RIO server.
Once the server is up and running, you can click on the links in the following query examples and the server should return a text document holding the return value of the respective query.
Most of the examples simply return their argument(s).
To make the output of the following example queries more readable, I added some additional whitespace (newlines and spaces).
2.2. Query available namespaces
Query available namespaces:
http://127.0.0.1:8080//rio%20namespaces
The service should return
return as 4
"PersonDAO" "RoleDAO" "rio" "TestDAO"
| |
2.3. Query procedures for namespace RIO
Query procedures for namespace
rio
:
http://127.0.0.1:8080//rio%20procedures%201%20name%20rio
The service should return
return ap 2
namespaces 0
: as
procedures 1
name s
: s
| |
2.4. Query procedures for namespace TestDAO
Query procedures for namespace
TestDAO
:
http://127.0.0.1:8080//rio%20procedures%201%20name%20TestDAO
The service should return
return ap 10
create 2
key s
value s
: TestVO
find 1
key s
: TestVO
echoBooleanArray 1
array ab
: ab
echoIntArray 1
array ai
: ai
echoLongArray 1
array al
: al
echoFloatArray 1
array af
: af
echoDoubleArray 1
array ad
: ad
echoStringArray 1
array as
: as
echoClassArray 1
array aTestVO
: aTestVO
echoHashArray 1
array ah
: ah
| |
Note:
VO
is short for ValueObject.
2.5. Query procedures for namespace RoleDAO
Query procedures for namespace
RoleDAO
:
http://127.0.0.1:8080//rio%20procedures%201%20name%20RoleDAO
The service should return
return ap 2
findById 1
id l
: RoleVO
findByName 1
name s
: RoleVO
| |
2.6. Query procedures for namespace PersonDAO
Query procedures for namespace
PersonDAO
:
http://127.0.0.1:8080//rio%20procedures%201%20name%20PersonDAO
The service should return
return ap 7
findById 1
id l
: aPersonVO
findByName 1
name s
: aPersonVO
create 1
person PersonVO
: PersonVO
remove 1
person PersonVO
: b
find 1
person PersonVO
: aPersonVO
findBySurname 1
surname s
: aPersonVO
findByMinMaxBirthdate 2
min t
max t
: aPersonVO
| |
2.7. Call the PersonDAO.create procedure
Call the PersonDAO.create procedure:
http://127.0.0.1:8080//PersonDAO%20create%201%20person%20(PersonVO%202%20forename%20Foo%20surname%20Bar
The service should return
return (PersonVO 7
forename s "Foo"
role_id l 1
surname s "Bar"
birthdate t 2005-08-25-17-52-04-781250000
id l 1
role (RoleVO 3
granted_procedures as 0
id l 1
name s "User"
name s "Foo Bar"
| |
2.8. Call the TestDAO.echoBooleanArray procedure
2.9. Call the TestDAO.echoIntArray procedure
2.10. Call the TestDAO.echoLongArray procedure
Call the
TestDAO.echoLongArray
procedure:
http://127.0.0.1:8080//TestDAO%20echoLongArray%201%20array%20al%203%20-9223372036854775807%2023%209223372036854775807
The service should return
return al 3
-9223372036854775807 23 9223372036854775807
| |
2.11. Call the TestDAO.echoFloatArray procedure
Call the
TestDAO.echoFloatArray
procedure:
http://127.0.0.1:8080//TestDAO%20echoFloatArray%201%20array%20af%205%20-2.2%20-1.1%200.123%201.12%202.23
The service should return
return af 5
-2.200000 -1.100000 0.123000 1.120000 2.230000
| |
2.12. Call the TestDAO.echoDoubleArray procedure
Call the
TestDAO.echoDoubleArray
procedure:
http://127.0.0.1:8080//TestDAO%20echoDoubleArray%201%20array%20ad%203%20-1.000000123%200.123456789%201.000000123
The service should return
return ad 3
-1.000000123 0.123456789 1.000000123
| |
2.13. Call the TestDAO.echoStringArray procedure
Call the
TestDAO.echoStringArray
procedure:
%20world.%22%20':%5E%5D'%20'a%20%5C%22b%20c%5C%22%20d'
The service should return
return as 7
"o n e" "two" "three" "four" "hello, world." ":^]" "a \"b c\" d"
| |
2.14. Call the TestDAO.echoClassArray procedure
Call the
TestDAO.echoClassArray
procedure:
http://127.0.0.1:8080//TestDAO%20echoClassArray%201%20array%20aTestVO%203%202%20key%20Foo1%20value%20Bar1%202%20key%20Foo2%20value%20Bar2%202%20key%20Foo3%20value%20Bar3
The service should return
return aTestVO 3
2 key s "Foo1" value s "Bar1"
2 key s "Foo2" value s "Bar2"
2 key s "Foo3" value s "Bar3"
| |
2.15. Call the TestDAO.echoHashArray procedure
Call the
TestDAO.echoHashArray
procedure:
http://127.0.0.1:8080//TestDAO%20echoHashArray%201%20array%20ah%203%202%20Key1_1%20Value1_1%20Key1_2%20Value1_2%202%20Key2_1%20Value2_1%20Key2_2%20Value2_2%202%20Key3_1%20Value3_1%20Key3_2%20Value3_2
The service should return
return ah 3
2 Key1_1 s "Value1_1"
Key1_2 s "Value1_2"
2 Key2_1 s "Value2_1"
Key2_2 s "Value2_2"
2 Key3_1 s "Value3_1"
Key3_2 s "Value3_2"
| |
auto-generated by "DOG", the TkScript document generator. Mon, 28/Dec/2015 14:27:05