2013-12-17 48 views
2

我有一个代码如下:执行星号回调的Perl命令?

1 sub do_leave { 
2 
3 my ($asterisk, $event) = @_; 
4 my $join_id; 
5 my $id = $astman->send_action({ Action => 'Getvar', 
6         Variable => 'join_id', 
7         Channel => $event->{'Channel'}, 
8         }, \&get_value, undef, \$join_id); 
9 
10 sleep(2); 
11 say "join_id is: $join_id"; 
12 
13 my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?"; 
14 my $sth = $dbh->prepare($sql); 
15 $sth->execute($join_id); 
16 } 
17 
18 sub get_value { 
19 my ($ast, $resp, $ref_join_id) = @_; 
20 for my $key (keys %$resp) { 
21  if ($key eq "PARSED") { 
22  $$ref_join_id = $resp->{$key}{"Value"}; 
23  } 
24 } 
25 } 

我使用Asterisk::AMI模块,用于从星号AMI获取信息。 do_leave子每当有人离开会议时被调用。我的问题是get_valuedo_leave的所有语句后执行的回调。 如何在第10行之前执行get_value回调。变量\$join_idsend_action是回调的第三个参数。在sql语句之前,我需要$join_id变量。

+0

是'send_id'保证调用'get_value'回调?所以你只是想在更新数据库之前确保回调已经被执行了?在这种情况下,我会立刻为您准备好*期货*的解决方案。 – amon

+0

@amon yes send_action将会执行'get_value'回调,但是在数据库更新之后,它在执行之前也不会做任何事情,因为'$ sth-> execute($ join_id);'needs'join_id'。 –

回答

1

我没有使用过Asterisk :: AMI,但我认为send_action方法采用回调方法的原因是结果异步返回。你无法保证需要多长时间。

一个快速简便的解决方案是将回调函数像这里面的数据库更新:我已经使用匿名子

sub do_leave { 

    my ($asterisk, $event) = @_; 
    my $get_value = sub { 
    my ($ast, $resp, $ref_join_id) = @_; 
    for my $key (keys %$resp) { 
     if ($key eq "PARSED") { 
      my $ref_join_id = $resp->{$key}{"Value"}; 
      my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?"; 
      my $sth = $dbh->prepare($sql); 
      $sth->execute($join_id); 
     } 
    } 
    }; 

    my $id = $astman->send_action({ Action => 'Getvar', 
            Variable => 'join_id', 
            Channel => $event->{'Channel'}, 
           }, $get_value); 

} 

通知,分配给一个变量,这样可以让大家分享变数在do_leave子外部和回调子部分之间(这称为闭包)。但是在这种情况下,可能不需要,因为没有共享变量。

+0

谢谢。我真的不知道把数据库更新放在回调函数中。 –

2

对于最小的变化你的脚本,

sub do_leave { 

    my ($asterisk, $event) = @_; 
    my $join_id; 

    my $sub = sub { 
    get_value(@_); 
    say "join_id is: $join_id"; 

    my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?"; 
    my $sth = $dbh->prepare($sql); 
    $sth->execute($join_id); 
    }; 
    my $id = $astman->send_action({ Action => 'Getvar', 
            Variable => 'join_id', 
            Channel => $event->{'Channel'}, 
           }, $sub, undef, \$join_id); 
    # sleep(2); 
}