Skip to content
Angga7Togk edited this page Mar 19, 2026 · 1 revision

IPC (Inter-Process Communication)

GamanJS provides a lightweight and high-performance IPC transport layer using Unix sockets. It allows efficient communication between processes with support for streaming and structured data handling.


Basic Usage

import { Gaman } from "gaman";
import type { IPC } from "gaman";

const gaman = Gaman<IPC>();

gaman.ipc('/tmp/gaman.sock', (ctx) => {
	if (ctx.stage === 'DATA') {
		console.log(ctx.json()); // parsed JSON (if valid)
		console.log(ctx.text()); // string
		console.log(ctx.body()); // raw Buffer

		ctx.send({
			name: 'Angga7Togk',
		});
	}

	if (ctx.stage === "OPEN") {
		// connection opened
	}

	if (ctx.stage === "CLOSE") {
		// connection closed
	}
});

gaman.mountServer();

Context Overview

Each IPC handler receives a ctx object that provides utilities to interact with the socket and incoming data.

Incoming Data

ctx.json() // parse JSON if possible
ctx.text() // return as string
ctx.body() // raw Buffer
  • json() attempts safe JSON parsing
  • text() returns UTF-8 string
  • body() returns raw binary data

Context Stages

OPEN

Triggered when a new connection is established.

if (ctx.stage === "OPEN") {
	// initialize connection
}

DATA

Triggered when data is received.

if (ctx.stage === "DATA") {
	const data = ctx.json();
}

CLOSE

Triggered when the connection is closed.

if (ctx.stage === "CLOSE") {
	// cleanup
}

Sending Data

ctx.send({
	message: "Hello from IPC",
});

Packet Framing

GamanJS uses a structured packet format to ensure reliable communication over streams:

[HEADER: payload size][TYPE][PAYLOAD]

Structure Breakdown

  • HEADER (4 bytes) Unsigned 32-bit integer (Big Endian) representing the total size of:

    TYPE + PAYLOAD
    
  • TYPE (1 byte) Indicates how the payload should be interpreted:

    0 = JSON
    1 = Text (UTF-8 string)
    2 = Buffer (raw binary)
    
  • PAYLOAD (N bytes) The actual data content


Example

[00000015][00][{"hello":"world"}]
  • 00000015 → total size (21 bytes)
  • 00 → type JSON
  • rest → JSON payload

Why This Matters

IPC and sockets are stream-based, meaning:

  • data can arrive in chunks
  • messages can be split or combined

This framing system ensures:

  • complete message reconstruction
  • correct parsing of multiple messages
  • safe handling of binary data

Notes

  • Always read the first 4 bytes to determine message length
  • Then read 1 byte for type
  • Then read the remaining payload
  • Multiple packets may exist in a single stream chunk

Client Examples

Bun

Bun.connect({
	unix: '/tmp/gaman.sock',
	socket: {
		open(socket) {
			socket.write(JSON.stringify({
				hello: "from bun"
			}));
		},
		data(socket, data) {
			console.log(data.toString());
		}
	}
});

Node.js (JavaScript)

import net from "net";

const client = net.createConnection({
	path: "/tmp/gaman.sock"
});

client.on("connect", () => {
	client.write(JSON.stringify({
		hello: "from node"
	}));
});

client.on("data", (data) => {
	console.log(data.toString());
});

client.on("end", () => {
	console.log("disconnected");
});

Java

import java.io.OutputStream;
import java.net.Socket;

public class IPCClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("localhost", 0); // placeholder (Unix socket needs library)

        OutputStream out = socket.getOutputStream();
        String json = "{\"hello\":\"from java\"}";
        out.write(json.getBytes());
        out.flush();

        socket.close();
    }
}

Note: Native Unix socket support in Java requires additional libraries such as junixsocket.


Notes

  • IPC is stream-based (not strict request-response)
  • Multiple messages may arrive in a single chunk
  • Use ctx.body() for maximum performance
  • JSON parsing is optional

Status

IPC is currently in preview and may evolve in future releases.