Chandra
view release on metacpan or search on metacpan
lib/Chandra/Socket/Hub.pm view on Meta::CPAN
package Chandra::Socket::Hub;
use strict;
use warnings;
use IO::Select;
use Chandra::Socket::Connection;
our $VERSION = '0.24';
use Chandra;
# All socket helpers implemented as C functions in
# include/chandra/chandra_socket_hub.h
# _xs_generate_token is a C XSUB in socket_hub.xs
1;
__END__
=head1 NAME
Chandra::Socket::Hub - IPC server for coordinating Chandra instances
=head1 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
=head1 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
L<Chandra::Socket::Client> instances, and dispatches messages by channel
name.
=head1 CONSTRUCTOR
=head2 new
my $hub = Chandra::Socket::Hub->new(%args);
=over 4
=item name
(Required for Unix transport) Logical name used to derive the socket path.
=item transport
C<'unix'> (default) or C<'tcp'>.
=item port
(Required for TCP) Port number to listen on.
=item bind
Bind address for TCP. Defaults to C<'127.0.0.1'>.
=item tls_cert
Path to a PEM certificate file. Enables TLS when paired with C<tls_key>.
Requires L<IO::Socket::SSL>.
=item tls_key
Path to a PEM private key file for TLS.
=back
=head1 METHODS
=head2 on
$hub->on($channel => sub { my ($data, $conn) = @_; ... });
Register a handler for messages on C<$channel>. The callback receives
the decoded data hash and the sender's L<Chandra::Socket::Connection>.
=head2 on_connect
$hub->on_connect(sub { my ($conn) = @_; ... });
Called when a client completes the authenticated handshake.
=head2 on_disconnect
$hub->on_disconnect(sub { my ($conn) = @_; ... });
Called when a client disconnects.
=head2 broadcast
$hub->broadcast($channel, \%data);
Send a message to all connected clients.
=head2 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.
=head2 clients
my @names = $hub->clients;
Returns the names of all connected clients.
=head2 token
my $token = $hub->token;
Returns the authentication token. Pass this to TCP clients that cannot
read the token file.
=head2 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 C<$XDG_RUNTIME_DIR> / C<tmpdir> logic as the constructor.
=head2 poll
$hub->poll;
Non-blocking check for new connections and incoming messages.
Call this in your own event loop, or use C<run()> for a standalone loop.
=head2 run
$hub->run;
Blocking event loop that calls C<poll()> continuously. Useful for
standalone hub processes.
=head2 close
$hub->close;
Sends C<__shutdown> to all clients, closes all connections, removes the
socket and token files.
=head1 SECURITY
The Unix socket is created with 0600 permissions and placed in
C<$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 (C<.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 C<token>
parameter to L<Chandra::Socket::Client>.
For TCP transport over a network, enable TLS by passing C<tls_cert> and
C<tls_key> to the Hub, and C<< tls => 1 >> to the Client. This requires
L<IO::Socket::SSL>. Without TLS, TCP traffic (including the auth token)
is sent in plaintext.
=head1 SEE ALSO
L<Chandra::Socket::Client>, L<Chandra::Socket::Connection>, L<Chandra::App>
=cut
( run in 1.021 second using v1.01-cache-2.11-cpan-39bf76dae61 )