perl - 将 IO::Socket::IP 与 Mojo::IOLoop 一起使用
问题描述
我正在尝试通过 Mojo::IOLoop 和 Mojo::Promises 实现这些代码行同步执行的操作,但异步执行操作:
my $address = '192.168.1.240';
my $sock = IO::Socket::IP->new(PeerAddr => $address,
PeerPort => '9999',
Proto => 'tcp');
$sock->send($on);
my $data;
$sock->recv($data, 2048);
print $data;
这用于与 smartplug 通信,基于 Promise 的接口允许我抽象出事物,以便可以以相同的方式处理不同的插件(一些通过 HTTP 通信,一些通过 TCP 通信)。
现在我已经通过这样做取得了结果
sub talk_to_plug_p {
my ($addr, $command) = @_;
my $promise = Mojo::Promise->new;
my $port = 9999;
my $sock = IO::Socket::IP->new(PeerAddr => $addr,
PeerPort => $port,
Proto => 'tcp');
return $promise->reject("Could not open socket on $addr at port $port") unless $sock;
my $id = Mojo::IOLoop->client({ handle => $sock } => sub {
my ($loop, $err, $stream) = @_;
$stream->on(read => sub {
my ($stream, $bytes) = @_;
# -------------------
# THIS LOOKS BAD
# -------------------
remove_id($loop);
$promise->resolve($bytes);
});
$stream->on(error => sub {
my $err = shift;
$promise->reject($err);
});
$stream->write($command);
});
sub remove_id { shift->remove($id) };
return $promise;
}
talk_to_plug_p('192.168.1.240', $on)->then(sub { print @_ })->catch(sub { print shift });
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
现在这可行,但它看起来有点不对 - 特别是remove_id
部分,我想必须有比这更好的方法。我只是找不到它。
什么是更清洁的方式?即:在读取字节时关闭客户端,或者我可以显式关闭连接或类似的东西。
解决方案
推荐阅读
- excel - VBA代码使用不同列的小计求和
- c# - Visual Studio,调试器,在进入另一个类后越过断点运行
- python - 如何在 Python 3.6 的 if/else 中优化文本输出?
- python - 限制在 pytesseract 中检测到的字符数
- javascript - 使用 .rotate() 时,它会留下 1px Lines
- javascript - 从用逗号分隔的对象中收集数据并将自己作为单独的对象 - Javascript
- javascript - 重构passport.js认证代码
- java - 如何获取当前活动的实时流列表并按描述和位置过滤它们
- sql - 如何务实地查找 SQL WHERE 子句的条件
- sql-server - 对象“执行”、数据库“SSISDB”、架构“内部”的 SELECT 权限被拒绝