我有一段代码,使用IO :: Socket :: UNIX创建一个UNIX域套接字,并将其提供给IO :: Async :: Listener的实例,以处理侦听套接字并通知接收数据。然后,IO :: Async :: Listener被添加到IO :: Async :: Loop事件循环实例中。 当然,套接字是在受控管理器中动态创建的。
在某种情况下,我想从事件循环中删除套接字(完全删除它,或者在其他条件下暂时禁用它),但我不知道如何。
IO :: Async :: Loop提供通过$ loop-> remove($ notifier)从事件循环中删除IO :: Async :: Notifier对象,但创建通知程序由IO :: Async ::内部处理监听器(通过IO :: Async :: Stream,我推测?)。即使在我的脚本的Ctrl-C上,套接字文件也没有被删除,我只需要手动close $socket and unlink( $path )
套接字文件吗?
这是所需行为的抽象代码:
#!/usr/bin/perl
use IO::Async::Loop;
use IO::Async::Listener;
use IO::Socket::UNIX;
my $loop = IO::Async::Loop->new;
my $listener = IO::Async::Listener->new(
on_stream => sub {
my ( undef, $stream ) = @_;
$stream->configure(
on_read => sub {
my ( $self, $buffref, $eof ) = @_;
$self->write( $buffref );
$buffref = "";
return 0;
},
);
$loop->add( $stream );
},
);
$loop->add( $listener );
my $socket = IO::Socket::UNIX->new(
Local => "echo.sock",
Listen => 1,
) || die "Cannot make UNIX socket - $!\n";
$listener->listen(
handle => $socket,
);
my $condition = true;
while($condition) {
// this is probably wrong
$loop->remove( $listener );
$condition = false;
}
答案 0 :(得分:2)
你似乎有两个相关的问题。
您可以使用循环的remove
方法从循环中删除侦听器对象:
$loop->remove( $listener )
但是,从循环中删除侦听器不会取消套接字节点与文件系统的链接。为此,您需要建议的unlink
代码。
就个人而言,在像这样创建套接字的代码中,我使用END
块:
my $path = "echo.sock";
my $socket = IO::Socket::UNIX->new(
Local => $path,
Listen => 1,
) || die "Cannot make UNIX socket - $!\n";
END { $socket and unlink $path }
$SIG{INT} = $SIG{TERM} = sub { exit 1 };
$SIG
行需要确保SIGINT
和SIGTERM
仍然运行END
块,而不是仅仅导致perl
进程立即终止
最后,您应该注意,您可以使用更简洁的listen
方法,而不是在您的情况下明确创建UNIX
套接字,您可以
my $listener = ...
$loop->add( $listener );
$listener->listen(
addr => {
family => "unix",
socktype => "stream",
path => "echo.sock",
},
);
虽然在这种情况下你仍然需要END
阻止。