NAME

Chandra::Socket::Hub - IPC server for coordinating Chandra instances

SYNOPSIS

use Chandra::Socket::Hub;

# Unix socket (default)
my $hub = Chandra::Socket::Hub->new(name => 'myapp');

# TCP
my $hub = Chandra::Socket::Hub->new(
    transport => 'tcp',
    port      => 9000,
    bind      => '0.0.0.0',
);

# TCP with TLS (requires IO::Socket::SSL)
my $hub = Chandra::Socket::Hub->new(
    transport => 'tcp',
    port      => 9000,
    tls_cert  => '/path/to/cert.pem',
    tls_key   => '/path/to/key.pem',
);

$hub->on('status', sub {
    my ($data, $client) = @_;
    print "Got status from ${\$client->name}\n";
});

$hub->on_connect(sub {
    my ($client) = @_;
    $client->send('welcome', { version => '1.0' });
});

$hub->broadcast('config', { theme => 'dark' });
$hub->send_to('window-1', 'navigate', { path => '/' });

$hub->run;  # standalone event loop

DESCRIPTION

Hub acts as the server in a hub/client IPC topology. It listens on a Unix domain socket (default) or TCP socket, accepts connections from Chandra::Socket::Client instances, and dispatches messages by channel name.

CONSTRUCTOR

new

my $hub = Chandra::Socket::Hub->new(%args);
name

(Required for Unix transport) Logical name used to derive the socket path.

transport

'unix' (default) or 'tcp'.

port

(Required for TCP) Port number to listen on.

bind

Bind address for TCP. Defaults to '127.0.0.1'.

tls_cert

Path to a PEM certificate file. Enables TLS when paired with tls_key. Requires IO::Socket::SSL.

tls_key

Path to a PEM private key file for TLS.

METHODS

on

$hub->on($channel => sub { my ($data, $conn) = @_; ... });

Register a handler for messages on $channel. The callback receives the decoded data hash and the sender's Chandra::Socket::Connection.

on_connect

$hub->on_connect(sub { my ($conn) = @_; ... });

Called when a client completes the authenticated handshake.

on_disconnect

$hub->on_disconnect(sub { my ($conn) = @_; ... });

Called when a client disconnects.

broadcast

$hub->broadcast($channel, \%data);

Send a message to all connected clients.

send_to

$hub->send_to($client_name, $channel, \%data);

Send a message to a specific client by name. Returns false if the client is not connected.

clients

my @names = $hub->clients;

Returns the names of all connected clients.

token

my $token = $hub->token;

Returns the authentication token. Pass this to TCP clients that cannot read the token file.

socket_path

my $path = Chandra::Socket::Hub->socket_path($name);

Class method. Returns the socket file path for a given hub name, using the same $XDG_RUNTIME_DIR / tmpdir logic as the constructor.

poll

$hub->poll;

Non-blocking check for new connections and incoming messages. Call this in your own event loop, or use run() for a standalone loop.

run

$hub->run;

Blocking event loop that calls poll() continuously. Useful for standalone hub processes.

close

$hub->close;

Sends __shutdown to all clients, closes all connections, removes the socket and token files.

SECURITY

The Unix socket is created with 0600 permissions and placed in $XDG_RUNTIME_DIR (or the system temp directory) to limit access.

Hub generates a random authentication token on startup and writes it to a token file (.token beside the socket) with 0600 permissions. Clients must present the correct token during the handshake or the connection is rejected. For TCP transport, pass the token explicitly via the token parameter to Chandra::Socket::Client.

For TCP transport over a network, enable TLS by passing tls_cert and tls_key to the Hub, and tls => 1 to the Client. This requires IO::Socket::SSL. Without TLS, TCP traffic (including the auth token) is sent in plaintext.

SEE ALSO

Chandra::Socket::Client, Chandra::Socket::Connection, Chandra::App