2011-08-19 82 views
1

我有一個簡單的腳本,該腳本應綁定到SMSC並偵聽傳入的消息。我遇到的問題是,如果它沒有收到任何消息,它會超時。使用Net :: SMPP作爲ESME接收器的套接字超時

下面是腳本:

#!/usr/bin/perl 

use Net::SMPP; 
use Data::Dumper; 
$Net::SMPP::trace = 1; 

$smpp = Net::SMPP->new_receiver('--removed--', 
           port => '--removed--', 
           system_id => '--removed--', 
           password => '--removed--', 
           ) or die; 

while (1) 
{  
    $pdu = $smpp->read_pdu() or die; 

    print "Received #$pdu->{seq} $pdu->{cmd}:". Net::SMPP::pdu_tab->{$pdu->{cmd}}{cmd} ."\n"; 
    print "From: $pdu->{source_addr}\nTo: $pdu->{destination_addr}\nData: $pdu->{data}\n"; 
    print "Messsage: $pdu->{short_message}\n\n"; 
} 

這裏是我得到的錯誤:

premature eof reading from socket at /usr/lib/perl5/site_perl/5.8.8/Net/SMPP.pm line 2424. 
$VAR1 = undef; 

下面是從SMPP.pm相關子:

sub read_hard { 
    my ($me, $len, $dr, $offset) = @_; 
    while (length($$dr) < $len+$offset) { 
     my $n = length($$dr) - $offset; 
     eval { 
      local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required 
      alarm ${*$me}{enquire_interval} if ${*$me}{enquire_interval}; 
      warn "read $n/$len enqint(${*$me}{enquire_interval})" if $trace>1; 
      while (1) { 
       $n = $me->sysread($$dr, $len-$n, $n+$offset); 
       next if $! =~ /^Interrupted/; 
       last; 
      } 
      alarm 0; 
     }; 
     if ([email protected]) { 
      warn "ENQUIRE [email protected]" if $trace; 
      die unless [email protected] eq "alarm\n"; # propagate unexpected errors 
      $me->enquire_link(); # Send a periodic ping 
     } else { 
      if (!defined($n)) { 
       warn "error reading header from socket: $!"; 
       ${*$me}{smpperror} = "read_hard I/O error: $!"; 
       ${*$me}{smpperrorcode} = 1; 
       return undef; 
      } 
      #if ($n == 0) { last; } 
      if (!$n) { 
       warn "premature eof reading from socket"; 
       ${*$me}{smpperror} = "read_hard premature eof"; 
       ${*$me}{smpperrorcode} = 2; 
       return undef; 
       #return 0; 
      } 
     } 
    } 
    #warn "read complete"; 
    return 1; 
} 

在sub,它所觸及的if語句是$ n爲0或undef的語句。

我的猜測是套接字超時並斷開連接。我怎樣才能讓聽衆無限期地保持下去?

另外,這個監聽器在等待pdu時阻塞。有沒有阻止聽的方法?

我是一名電信工程師,他負責編程,我已經瀏覽了所有可找到的資料,但找不到答案。

回答

1

它看起來好像sysread()調用只是返回0.它只能這樣做,如果已知連接狀態斷開連接。既然你的方面沒有斷開或超時,我會推斷遠程方斷開。如果在您身邊發生超時,您應該無法看到消息premature eof...

因此,您已經'無限期地保持收聽者',因爲您沒有設置enquire_interval選項。

關於'有沒有辦法在沒有阻塞的情況下聽取?'description section最後描述了異步模式:Module can also be used asynchronously by specifying async=>1 to the constructor。你必須自己實現數據輪詢。

+1

我試過了一個異步實現,但當沒有數據通過線路時它仍然超時。 – Alo

+0

我所做的是捕捉錯誤並重新連接。即使我仍然看到eof錯誤,它仍然有效。有沒有更優雅的做法? – Alo

-1

我也收到提前終止相同的錯誤。

對於阻塞,您可以對另一個進程進行fork或線程並且兩者都可以並行運行。沒有辦法阻止。

0

您是否嘗試爲查詢鏈接(SMPP ping)超時設置參數?

在您new_receiver,驗證是否「enquire_interval」參數存在,並將其設置爲15秒,例如...

我試圖與new_transceiver()方法,和它的作品。

my $smpp = Net::SMPP->new_transceiver(
    $self->host, 
    port    => $self->port, 
    system_id   => $self->user, 
    password   => $self->password, 
    smpp_version  => $self->version, 
    interface_version => $self->interface_version, 
    enquire_interval => $self->timeout, 
    addr_ton  => $self->addr_ton, 
    addr_npi  => $self->addr_npi, 
    source_addr  => $self->source_addr, 
    source_addr_ton => $self->source_addr_ton, 
    source_addr_npi => $self->source_addr_npi, 
    dest_addr_ton => $self->dest_addr_ton, 
    dest_addr_npi => $self->dest_addr_npi, 
    system_type  => $self->system_type, 
    facilities_mask => $self->facilities_mask 
) or die "Could not connect to $self->host: $!"; 

它(Net :: SMPP)自動處理查詢鏈接。

+0

也許這會幫助:[Net :: SMPP#Misc.Notes](https://metacpan.org/pod/Net::SMPP#MISC.-NOTES) – eddy85br