【发布时间】:2014-07-16 20:43:51
【问题描述】:
如果这个问题太含糊,我真的很抱歉;我会尽力尝试总结我的问题。这是我第一次使用 Perl,我想我已经接近了。
我有一个哈希值,用于存储从 Asterisk 收到的呼叫信息。
每个调用都应该在哈希中有一个条目,键是唯一的 ID(我知道这可能是不好的做法,但键会在脚本结束时被销毁,所以我不担心重复)。
当我从 Asterisk 获取数据时,我需要不断地将新数据附加到哈希元素,然后在某些时候将结果打印到 TCP 套接字。
这就是我所拥有的。我的问题是我似乎无法将新数据附加到同一个哈希键。
请原谅我的业余爱好;任何有关格式化/最佳实践/任何事情的帮助都将不胜感激!
use Asterisk::AMI;
use IO::Socket;
use strict;
use warnings;
use Data::Dumper;
my %call;
my $sock = new IO::Socket::INET(
PeerAddr => '127.0.0.1',
PeerPort => '1234',
Proto => 'tcp',
);
die "Could not create socket: $!\n" unless $sock;
my $astman = Asterisk::AMI->new(
PeerAddr => '127.0.0.1',
PeerPort => '5038',
Username => 'user',
Secret => 'secret',
Events => 'on',
Handlers => {
#default => \&eventhandler,
Dial => \&ringcheck,
Bridge => \&bridgecheck,
Newchannel => \&newchannel
}
);
die "Unable to connect to asterisk" unless ($astman);
# Default event handler
sub eventhandler {
my ($ami, $event) = @_;
print 'Got Event: ', $event->{'Event'}, "\r\n";
}
sub newchannel {
my ($ami, $event) = @_;
if ($event->{'Context'} eq "from-trunk") {
$call = $event->{'Uniqueid'} => {
caller_name => $event->{'CallerIDName'},
caller_number => $event->{'CallerIDNum'},
dnis => $event->{'Exten'}
};
}
}
sub ringcheck {
my ($ami, $event) = @_;
if ($event->{'SubEvent'} eq "Begin") {
$call = $event->{'UniqueID'} => {
system_extension => $event->{'Dialstring'},
dest_uniqueid => $event->{'DestUniqueID'}
};
print $sock "R|", $call{ $event->{'UniqueID'} }{'caller_name'}, "|",
$call{ $event->{'UniqueID'} }{'caller_number'}, "|",
$call{ $event->{'UniqueID'} }{'system_extension'}, "||",
$call{ $event->{'UniqueID'} }{'dnis'}, "\r\n";
}
}
sub bridgecheck {
my ($ami, $event) = @_;
if ($event->{'Bridgestate'} eq "Link") {
# Call has started
print $sock "A|", $call{ $event->{'UniqueID'} }{'caller_name'}, "|",
$call{ $event->{'UniqueID'} }{'caller_number'}, "|",
$call{ $event->{'UniqueID'} }{'system_extension'}, "||",
$call{ $event->{'UniqueID'} }{'dnis'}, "\r\n";
}
elsif ($event->{'Bridgestate'} eq "Unlink") {
# Call has ended
}
}
EV::loop
需要明确的是,问题是我应该如何将新数据(例如在 ringcheck 子例程中)附加到在 newchannel 子例程中创建的 %call 哈希中?
【问题讨论】:
-
你能把它变成一个更简单的例子吗?对于不了解 Asterisk 的人来说,现在的编写方式很难理解(这甚至与您所询问的内容无关)。
-
=>仅表示,(除了它在其 LHS 上自动引用裸词)。我不知道你在做什么,但$call = $event->{'UniqueID'} => { ... };是错误的。事实上,这是一个警告。如果您告诉我们您遇到了错误,那就太好了。 -
@daotoad:这与 OP 已有的有什么不同?
-
@Borodin,主要区别在于它将内容列表与分隔符分开。 OP 的版本将分隔符(语句和字段)与字段内容混合在一起。
printf STATEMENT/STATEMENT_DELIMITER, join FIELD_DELIMITER, LIST_OF_FIELDS;。对于更高级的 perl 用户,我可能会添加一个映射来进行重复的 $call{} 哈希查找。map { defined $cdr{$_} ? $cdr{$_} : $_ } 'A', 'caller_name', 'caller_number' ...;使用qw//也可以很好,但是由于我们需要在列表中使用一个空字符串,它会变得很混乱,尤其是当您不能在示例中使用换行符时。 -
@daotoad:你没有理解我的意思。也许您发布的代码中有更多的布局空白,但它已被布局引擎吞噬。除了这样的空格之外,您的替代语句完全匹配 OP 在其子例程中的
print语句bridgecheck