This project contains a wrapper object to work with shared memory and an implementation of IPC channel based on that.
- Author: Jiří Janoušek
- License: BSD-2-Clause
- Supported Runtimes: Vala/C, Python 3.6/asyncio, JavaScript/NodeJS
- Supported Platforms: Unix with POSIX shared memory and POSIX semaphores.
- Documentation: Vala → lib/doc, Python → TODO, JavaScript -> TODO.
- Examples: See examples section bellow or in ./examples
- Test Suite: TODO
- Status: Early alpha, ABI-unstable
- Source: examples/vala/channel.vala
- Run as:
./channel server "Message from server."
and./channel client "Message from client."
Shmch.Mode role;
void response_received(uint8[] data) {
stdout.printf("%s: Response received: %s\n", role.to_string(), (string) data);
}
void notification_received(uint8[] data) {
stdout.printf("%s: Notification received: %s\n", role.to_string(), (string) data);
}
void request_received(Shmch.IncomingRequest request) {
stdout.printf("%s: Request received: %s\n", role.to_string(), (string) request.get_data());
request.send_response(request.get_data());
}
int main(string[] args) {
if (args.length == 3) {
role = args[1] == "server" ? Shmch.Mode.SERVER : Shmch.Mode.CLIENT;
var message = args[2];
var channel = new Shmch.Channel("/test", role);
channel.set_notification_callback(notification_received);
channel.set_request_callback(request_received);
channel.open();
channel.request(message.data, response_received);
stdout.printf("Request sent: %s\n", message);
channel.notify(message.data);
while (true) {
channel.send_receive(true);
Thread.usleep(100000);
}
channel.close();
return 0;
} else {
stderr.printf("Usage: %s server|client message\n", args[0]);
return 1;
}
}
- Source: examples/python/channel.py
- Run as:
python3.6 examples/python/channel.py server "Message from server."
andpython3.6 examples/python/channel.py client "Message from client."
import asyncio
from typing import List
from shmchannel import MODE_SERVER, MODE_CLIENT, Channel
mode = None
def notification_received(data: bytes):
print("%s: Notification received: %s" % (mode, data.decode()))
async def _request_received(data: bytes) -> bytes:
for i in range(5, 0, -1):
print("%s: Request received: %s ... %d" % (mode, data.decode(), i))
await asyncio.sleep(1)
return data
async def main(args: List[str]) -> int:
global mode
if len(args) == 3:
mode = MODE_SERVER if args[1] == "server" else MODE_CLIENT
message = args[2]
channel = Channel("/test", mode)
channel.set_notification_callback(notification_received)
channel.set_request_callback(_request_received)
channel.open()
task = asyncio.ensure_future(channel.send_receive())
channel.notify(message.encode())
print("Request sent:", message)
data = await channel.request(message.encode())
print("%s: Response received: %s" % (mode, data.decode()))
await task
channel.close()
return 0
else:
print("Usage: %s server|client message" % args[0])
return 1
if __name__ == "__main__":
import sys
loop = asyncio.get_event_loop()
sys.exit(loop.run_until_complete(main(sys.argv) or 0))
- Source: examples/nodejs/channel.js
- Run as:
node examples/nodejs/channel.js server "Message from server."
andnode examples/nodejs/channel.js client "Message from client."
const {Channel, StringDataConverter, MODE_CLIENT, MODE_SERVER} = require('shmchannel')
function onNotification(data) {
console.log("Notification received: %sn", data)
}
function onRequest(data, respond) {
console.log("Request received: %s", data)
respond("You have sent: " + data)
}
async function main(args) {
if (args.length === 4) {
let role = args[2] === "server" ? MODE_SERVER : MODE_CLIENT
let message = args[3]
let channel = new Channel("/test", role, onRequest, onNotification, new StringDataConverter())
channel.open()
let loop = channel.startCommunication()
console.log("Request sent: %s", message)
let response = await channel.request(message)
console.log("Response received: %s", response)
channel.notify(message)
await loop
channel.close()
return 0;
} else {
console.log("Usage: %s %s server|client message", args[0], args[1]);
return 1;
}
}
main(process.argv).catch(function(e){console.log("Error: %s", e)})
- Vala server:
./channel server "Message from server."
:
Request sent: Message from server.
SHMCH_MODE_SERVER: Notification received: Message from client.
SHMCH_MODE_SERVER: Request received: Message from client.
SHMCH_MODE_SERVER: Response received: Message from server.
- Python client:
python3.6 examples/python/channel.py client "Message from client."
:
Request sent: Message from client.
1: Notification received: Message from server.
1: Request received: Message from server. ... 5
1: Response received: Message from client.
1: Request received: Message from server. ... 4
1: Request received: Message from server. ... 3
1: Request received: Message from server. ... 2
1: Request received: Message from server. ... 1
- Vala/C Library:
- GNU Make
- Python 3
- Valac
- g-ir-compiler
- glib-2.0 and friends (and respective GIR XML files)
- Python Bindings:
- Python 3.6
- setuptools
- cffi
- NodeJS Bindings:
- NodeJS (including headers)
- Python 3
- node-gyp
- C++ compiler
./configure --help
./configure ...
make all
make install
make DESTDIR=... install