Таймаут сокета с использованием Net :: SMPP в качестве ESME-приемника - PullRequest
1 голос
/ 19 августа 2011

У меня есть простой скрипт, который должен привязываться к SMSC и прослушивать входящие сообщения.У меня проблема в том, что время ожидания истечет, если он не получит никаких сообщений.

Вот скрипт:

#!/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 ($@) {
            warn "ENQUIRE $@" if $trace;
            die unless $@ 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;
}

В подпункте оператор if, в который он попадает, это тот, где $ n равно 0 или undef.

Я предполагаю, что время ожидания сокета и отключение.Как я могу держать слушателя включенным бесконечно?

Кроме того, этот слушатель блокируется во время ожидания pdu.Есть ли способ слушать без блокировки?

Я инженер по телекоммуникациям, который занимается программированием на стороне, и я просмотрел весь материал, который мог найти, но не смог найти ответ.

Ответы [ 3 ]

1 голос
/ 20 августа 2011

Похоже, что вызов sysread() просто возвращает 0. Он может сделать это только в том случае, если известно, что состояние соединения отключено. Так как ваша сторона не отключилась или тайм-аут, я бы сделал вывод, что удаленная сторона отключена. Если на вашей стороне произошел тайм-аут, вы не должны были видеть сообщение premature eof....

Итак, вы уже ' держите слушателя на неопределенный срок ', поскольку вы не устанавливаете опцию enquire_interval.

Относительно ' Есть ли способ прослушивания без блокировки? ' В разделе описание в конце описывается асинхронный режим: Module can also be used asynchronously by specifying async=>1 to the constructor. Вы должны сами выполнить опрос данных.

0 голосов
/ 19 января 2016

Вы пытались установить параметр для таймаута запроса ссылки (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 голосов
/ 02 января 2013

Я также получаю ту же ошибку преждевременного завершения.

Для блокировки вы можете форкировать или нанизывать другой процесс, и оба могут работать параллельно.Обойти блокировку невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...