如果这个问题太模糊,我真的很抱歉;我会尽力尝试总结我的问题。这是我第一次搞乱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
子例程中将新数据附加到%call
子例程中创建的newchannel
哈希?
答案 0 :(得分:4)
由于您没有声明$call
,因此您必须收到来自use strict
的错误消息。如果你告诉我们,那会有很大的帮助。
请使用最小缩进:通常使用四个或更少的空格,我使用两个。大缩进使代码难以遵循
即使在Windows上,也不要使用"\r\n"
终止输出行。 Perl处理所有这些,你应该在任何平台上打印"\n"
换行
哈希%call
是与标量$call
完全独立的变量,因此分配给$call
根本不会影响您的哈希值。如果strict
到位,您会看到错误,因为$call
尚未定义
要分配给哈希元素,请使用$hash{$key}
。可以把它想象成一个数组元素,但是哈希元素不是整数,而是用字符串索引。如果要将常量用作散列键,则可以省略引号,因此$call{'caller_name'}
与$call{caller_name}
现在只看ringcheck
,如果将$event->{UniqueID}
的值复制到标量变量而不是使用相同的哈希,它会使您的代码更简洁,更容易理解元素无处不在。您可以使用哈希引用$call{$unique_id}
我已将您的代码更改为可能有效的内容,或者至少可以帮助您。我使用printf
将格式与数据分开,使其更具可读性。
sub ringcheck {
my ($ami, $event) = @_;
if ($event->{SubEvent} eq 'Begin') {
my $unique_id = $event->{UniqueID};
my $this_call = $call{$unique_id};
$this_call->{system_extension} = $event->{Dialstring};
$this_call->{dest_uniqueid} = $event->{DestUniqueID};
printf $sock "R|%s|%s|%s||%s\n",
$this_call->{caller_name},
$this_call->{caller_number},
$this_call->{system_extension},
$this_call->{dnis};
}
}
答案 1 :(得分:1)
您使用错误的运算符进行分配。 =>
是,
的同义词,其附加效果是引用其左侧操作数(除非它是变量。)
我对Asterisk一无所知,但你可能想要:
$event->{'UniqueID'} = {
system_extension => $event->{'Dialstring'},
dest_uniqueid => $event->{'DestUniqueID'}
};
我不确定你在$call
尝试做什么。