[TOC]
sock-rpc#
- This a Node.js module that implements an RPC server on top wire-protocol from Arma 3 sock.dll extension.
Changelog
- 1.0.8
- Fix broken typeof2 function
- Add test case for rawToJSON
- 1.0.7
- Pull fix for Context from @Fusselwurm
- 1.0.6
- Fix bug where
1.#QNAN
value was not being parsed correctly
- Fix bug where
- 1.0.5
- Fix bug where booleans where not being handled when using RAW SQF format
- 1.0.4
- Add support for requests formatted as Raw SQF (to help with client-side performance)
- Add support command line arguments --trace-req
- 1.0.3
- Add support command line arguments --trace-send, and --trace-recv
- Extend the high level RPC protocol to allow passing "accept" property (supports "application/sqf", and "application/json")
- Add Client class that can be used to communicate with a remote sock-rpc server
- 1.0.1 - Major version bump due to design changes in callback mechanism
- Added SEVERE level logging to show the the actual JSON string when parsing error happens
- 1.0.0 - Major version bump due to design changes in callback mechanism
- Improved logging using the util-logging module
- Improved command line processing using yargs module
- Design change: callback passed into registered RPC functions are now always the last argument
- Design change: callback passed into registered RPC functions have now the following signature: callback(err, result)
- 0.0.2 - Update to add license file
- 0.0.1 - Initial release
Prerequisites
- Download and install Node.js
Installation
- From the head of the master branch
.
npm install -g git+https://bitbucket.org/micovery/sock-rpc.git
.
- From the npmjs.org repository
.
npm install -g sock-rpc
.
How to use
Create a Node.js JavaScript file (e.g. example.js) containing the functions to be used by the RPC server.
"use strict"; var rpc = ; /** * Echo back all arguments passed. * echo(...,callback); */rpc; /** * Get date (no arguments) */rpc;rpc;
.
All registered method's must use the callback mechanism to pass the result to the client, and by doing so indicate that the execution is complete.
If a method does not invoke the callback, the client side will likely hang while it waits for a response from the server.
.
In order to indicate that an error has happened, you can pass an error as the first argument to the callback.
.
;
Starting the Server
The following commands shows how to start the RPC server on port 1337, and IPv6 loolback address ::1 using the Windows command-line.
set NODE_PATH=%AppData%\npm\node_modules
node example.js -port=1337 -host=::1
.
API
-
listen([host], [port])
-
host (type: string, optional) - Host name, or address to listen on
If not provided, it defaults to command line argument -host=
If -host is not provided, it defaults to localhost
. -
port (type: number, optional) - Port number to listen on
If not provided, it defaults to command line argument -port=
If -port is not provided, it defaults to a random available port
.
-
-
register(functions)
- functions (type: object, required) - An object containing functions
.
- functions (type: object, required) - An object containing functions
-
register(name, function)
-
name (type: string, required) - Host name, or address to listen on
-
function (type: function, required) - Function to register
.
-
Low-Level Protocol
At the lowest level, this module uses the SOCK-TCP wire-protocol from the sock.dll Arma 3 extension, acting as the server. .
//First, wait for client to send a request message
server: recv: request-header-foo (4 bytes, unsigned long, network byte order, length of the body that follows)
server: recv: request-body-foo (variable bytes, actual request message data)
//then send the response message
server: send: response-header-foo (4 bytes, unsigned long, network byte order, length of the body that follows)
server: send: response-body-foo (variable bytes, actual response message data)
.
That's pretty much it, server receives a request message, and replies with a response message.
.
- The server does not guarantee that response messages are sent to client matching the same order as the request messages.
- The client must either send only one request message at a time, and wait for the response ... or keep track of of the messages using sequence IDs.
- In Arma 3, the execution of extensions is single threaded. This guarantees that only one request packet is sent at a time.
- Client may send a zero-length request message. The server must ignore zero-length messages and continue on processing.
High-Level Protocol
At a high level, this module uses a protocol similar to JSON-RPC, for client requests.
For server responses, on the other hand, they are formatted as SQF code that can be compiled dynamically inside the game.
.
//First wait for client to send a JSON-RPC request
server: recv: {"method":"methodName", "params": ["param1", "param2"],...]}
//then send the SQF response
server: send: [false,"response"]
.
The response to a client request is always an SQF array with two elements.
[error-state, mapped-response-data]
.
-
error-state (type: boolean) - This is an indicator of whether or not an error occurred while processing the request.
- tue - if an error occurred processing the client's request
- false - if no error occurred processing the client's request
.
-
mapped-response-data
- The mapped-response-data, as the name indicates, is simply the output of the RPC invocation mapped into its equivalent SQF representation.
- When an error occurs (error-state is true), then mapped-response-data is an SQF string containing explanation of the error.
- If no error occurs, then the mapped-response-data can be of any SQF data type.
.