yuri123 has asked for the wisdom of the Perl Monks concerning the following question:

I wrote a simple script to see how I can use UNIX domain socket to implement a client/server pair

The script can be ran as client/server.

The client side does a push_write, the server does push_read.
Unfortunately the whole thing doesn't seem to work, both server and client simply sit there with no output.
Please advise, any pointers will be greatly appreciated. I am sure I missed something trivial.
I start the server first (SCRIPT) and the client next (SCRIPT 1).

#!/usr/bin/perl use v5.10; use strict; use warnings; use AnyEvent::Socket; use AnyEvent::Handle; my $client = shift; # undef - server, or client my $path = "/tmp/socket"; my %data = (a => b => c => d =>); my $cv = AnyEvent->condvar; # Will send when client breaks connectio +n if ($client) { # Client tcp_connect( "unix/", $path, sub { if (!@_) { # Error print STDERR "Failed connect to $path:$!\n"; $cv->end; return; } print "Client connected to $path\n"; my ($fh) = shift; #Create a handle and save it my $hdl; $hdl = AnyEvent::Handle->new( fh => $fh, on_error => sub { my ($hdl, $fatal, $msg) = @_; AE::log error => $msg; $hdl->destroy; $cv->send; }, on_eof => sub { my ($hdl1, $fatal, $msg) = @_; $hdl1->destroy; # destroy handle AE::log info => "Done."; $cv->send; } ); # Write to the server $hdl->push_write (storable => \%data); 1; }, ) } else { # Server print "Server\n"; tcp_server( "unix/", $path, sub { # Accept callback and start rolling my ($fh, $host, $port) = @_; print "ACCEPTED:host=$host\n"; my $hdl = AnyEvent::Handle->new( fh => $fh, on_error => sub { my ($hdl1, $fatal, $msg) = @_; AE::log error => $msg; $hdl1->destroy; $cv->send; }, on_eof => sub { my ($hdl1) = @_; $hdl1->destroy; # destroy handle AE::log info => "Done."; } ); # Read from the client $hdl->push_read (storable => sub { my ($hdl1, $data) = @_; print "Read @{[ref($data)]}\n"; }); 1; }, ); print "Listening on $path\n"; } $cv->recv;

Replies are listed 'Best First'.
Re: AnyEvent server/client don't cooperate
by NERDVANA (Priest) on Oct 04, 2023 at 07:38 UTC

    You need to keep the handle '$hdl' in scope. For the client, you can just move the declaration to global scope. For the server, you need to put them into some sort of global hash so that there can be multiple of them, and when the connection closes, you can remove the one that closed. Of course, in an object-oriented program you would have the server object maintain the connection set in an attribute, so that when the server goes out of scope it closes all its connections.

    A less recommended quick-and-dirty way to keep them alive is to have it make a reference to itself, like $hdl->{self}= $hdl; and then you can have the on_error and on_eof remove that reference and allow it to get freed.

Re: AnyEvent server/client don't cooperate
by gnosti (Chaplain) on Oct 04, 2023 at 07:02 UTC
    Hi yuri123,
    If you just want to do a client/server pair, I think it will be a lot simpler to do it without AnyEvent (which I like and use btw). Usable code for your purpose appears in perlipc. I'd suggest you get this part working and later figure out the wrinkles of AnyEvent.