Hey All,
I am the developer of the jni.dll extension, that brings support for the JVM in Arma 3. Check it out here if you have not already done so.
While working on that extension, I felt the pain of the slow development cycle ... having to compile the Java code, rebuild jar files, restart the game, etc.
I wanted to develop with something less "enterprisy", with faster turn-around, and more in-tune with the online community of developers.
And so, I decided to bring Node.js in into the picture ... what is Node.js you ask?
If you simply want to use JavaScript with your missions, then you should use Sima's JavaScript for Arma (@JS addon).
With Node.js, on the other hand, you get the benefit of an extensive (and growing) set of community provided packages.
The packages are available through the Node Package Manager (see https://npmjs.org). In fact, one of the main components of this release, is implemented as a node package itself.
How it works
It's just a simple client-server model between SQF side (client), and the Node.js side (server).
On the SQF side, there is a library called sock.sqf
On the Node.js side, there is a node package (sock-rpc), that allows you to setup an RPC (remote procedure call) server.
The glue between these two, is a C/C++ extension called sock.dll.
The extension transparently manages a TCP/IP socket connection to the remote server.
It acts a middle man relaying the requests originating from the SQF code, and serving back the response of the "remote" side.
Now, when I say "remote", I mean outside of the game. The extension is not intended to communicate with a truly remote (in another machine) Node.js server. If that's the case, then the network overhead can become unacceptable. As long as your "remote" side sits on the loop-back address (::1 or 127.0.0.1), then the communication never goes out of the TCP/IP stack.
Prerequisites
1. Visual C++ Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=26999)
2. Node.js (http://nodejs.org/download/)
Components
1. sock.dll - This is a C/C++ extension that allows communication between SQF (using SOCK-SQF protocol), and a "remote" server (using SOCK-TCP protocol).
2. sock-rpc - This a Node.js module that implements the RPC server side, on top of the SOCK-TCP protocol
3. sock.sqf - This is small library that implements the RPC client side, on top of SOCK-SQF protocol
What are those protocols: SOCK-SQF, and SOCK-TCP? ... you may be asking yourself.
I made them up :), to describe the communication between the components.
If you want to read more on them, jump to the documentation: SOCK-SQF Protocol, SOCK-TCP Protocol.
Extension setup
Place the sock.dll file in the Arma 3 directory (C:\Program Files (x86)\Steam\steamapps\common\Arma 3\)
The extension reads configuration parameters from the Arma 3 process command line arguments.
There are two required command line arguments:
1. -sock_host
You must set this to the host name, or IP address of the "remote" server side (e.g. ::1)
2. -sock_port
This is the port number of the "remote" server side.
Server side model
This can be any Node.js application using the "sock-rpc" module, to expose methods that can be invoked from SQF.
The following example shows a simple RPC server with a "getDate" method, and an "echo" method.
"use strict";
var rpc = require('sock-rpc');
/**
* Echo back all arguments passed.
* echo(...,callback);
*/
rpc.register("echo", function () {
var args = Array.prototype.slice.call(arguments, 0);
var callback = args.pop();
callback(null, args);
});
/**
* Get date (no arguments)
*/
rpc.register("getDate", function (callback) {
callback(null, new Date().toString());
});
rpc.listen("::1", 1337);
Client side model
From the SQF code, you can use the function "sock_rpc", to send requests over to the "remote" Node.js side.
//Example for using the sock_rpc function
private["_method", "_response", "_params"];
_method = "getLocalTime";
_params = ["PST"];
_response = [_method, _params] call sock_rpc;
if (isNil "_response") exitWith {
player globalChat format["Error occurred while invoking the %1", _method];
}
else {
player globalChat _response;
};
Data mapping
Underneath it all, the sock.sqf library takes care of serializing your request into proper JSON that can be evaluated on the "remote" Node.js side.
Also, on the way back, the sock-rpc Node.js module takes care of serializing the responses into SQF that can be compiled by the game engine.
For most cases, SQF and JSON can be mapped back and forth pretty nicely (except when mapping objects).
Here is the full details of the data mapping logic:
//SQF to JSON mapping
* SQF array, is mapped directly to JSON array
* SQF number, is mapped directly to JSON number
* SQF string, is mapped directly to JSON string (double-quotes escaped, i.e. "\"")
* SQF nil, is mapped to JSON null
* SQF objNull, is mapped to JSON null
* SQF objects, are mapped to JSON object with the following fields: {"netId": "0:1", "name": "player1"}
//JSON to SQF mapping
* JSON array, is mapped directly to SQF array
* JSON number, is mapped directly to SQF number
* JSON string, is mapped directly to SQF string (double-quotes escaped, i.e. """")
* JSON undefined, is mapped to SQF nil
* JSON null, is mapped to SQF nil
* JSON objects, are mapped to SQF code-block with the following structure: {[["key1", "value1"], ["key2", "value2"]]}
Source Code
Source is available in the following repositories:
1. Git repo for the sock.dll extension
https://bitbucket.org/micovery/sock.dll/
2. Git repo for the Noe.js sock-rpc server module
https://bitbucket.org/micovery/sock-rpc
3. Git repo for the sock.sqf RPC client library
https://bitbucket.org/micovery/sock-rpc.mission
Demo Node.js Extension & Mission
I have put together a mission to demo the setup of the Node.js sock-rpc server, and the sock.dll extension.
You can read the full instructions for the setup, in the git repository for sock.sqf library itself.
or, watch this video:
Additional documentation
The README files on the git repositories for each component contain:
1. Full API documentation
2. Protocol information,
3. How to enable debug, and logging levels
Summary/Reflection
Keep in mind that all the code is fairly new, and there will be bugs ... please report them, and I will try fix it on a timely manner.
Or better yet, you can fix them and contribute back.
What would you want to do with it? Let me know in this thread ...
All of the code is under MIT license, enjoy.
Cheers,
micovery