Как может Perl CGI-скрипт взаимодействовать с демоном на веб-сервере? - PullRequest
1 голос
/ 14 ноября 2009

Я создаю веб-интерфейс для мониторинга встроенной системы. Я создал Perl-скрипт, который запускает удаленные команды и собирает выходные данные из этой системы. Теперь мне нужен веб-интерфейс, который выполняет вызовы этого скрипта (выполняет команду remotes) и отображает данные на веб-странице.

Прежде всего мне нужно сделать мой скрипт как процесс-демон который может принимать запросы от веб-сервера. Я могу выбрать любую серверную технологию, если она может взаимодействовать с этим сценарием Perl. Чтобы было проще, я могу выбрать Perl / CGI, который может общаться с этим демон-скриптом Perl.

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

Есть ли уже доступные модули Perl, которые могут упростить передачу моих сообщений без меня беспокоиться о том, как происходит общение? У меня есть удаленные команды в виде простого текста, и я хочу вернуть данные в XML / JSON.

Ответы [ 3 ]

1 голос
/ 15 ноября 2009

В прошлом, когда мне нужно было сделать что-то подобное, я обычно обрабатывал общение одним из двух способов:

1) Если ответ необходим в режиме реального времени для немедленной отправки пользователю (как это, похоже, имеет место здесь), тогда использование сокетов для общения с демоном - это путь. Существуют и другие варианты с общей памятью, каналами и тому подобным, но использование сокетов дает вам простой путь масштабирования, если / когда вам нужно разбить интерфейсный веб-сервер и серверный демон на отдельные машины.

2) Если ответ не критичен ко времени, я обычно помещал поступающие команды в очередь, хранящуюся в таблице базы данных, а затем периодически вызывал демон для новых задач. Это, как правило, немного проще в реализации и масштабируется даже лучше, чем опция на основе сокетов, при условии, что вы можете справиться с ограничением всей коммуникации, проходящей через базу данных.

1 голос
/ 15 ноября 2009

Вы не объяснили, почему существующий сценарий perl нельзя запустить непосредственно из сценария Perl / CGI? Мне кажется, это самый простой путь, поскольку он не предусматривает создание другого канала связи:

client ⇒ apache ⇒ your CGIzed existing script ⇒ embedded system

вместо:

client ⇒ apache ⇒ new CGI script ⇒ existing script ⇒ embedded system

Полагаю, причина в том, что вы ожидаете, что скрипт CGI будет выполняться несколько раз одновременно, а встроенная система не сможет обрабатывать несколько соединений.

Но даже в этом случае наличие демона для единственной цели сериализации кажется излишним. Вы можете использовать блокировку в скрипте CGI для защиты критического кода связи, например:

open(my $lock, ">", $lockfilename);
flock($lock, LOCK_EX);
... critical code...
flock($lock, LOCK_UN);

Обратите внимание, что часть "критического кода" может встраивать существующий сценарий или выполнять его.

Если, несмотря на все это, вы все еще хотите отделить CGI от демона команды, вот шаблоны для клиентской и серверной частей связи на основе сокетов. Во-первых, клиент, который является частью CGI:

use IO::Socket::INET;
$sock = IO::Socket::INET->new('localhost:9000');
print $sock "Comand\n";
$result = <$sock>;
... do something with the result ...
$sock->close;

И это основной цикл демона:

package MyServer;
use base Net::Server;
sub process_request {
    my $self = shift;
    while (<STDIN>) {
        chomp;
        print "This is my answer to the command '$_'.\r\n";
    }
}
MyServer->run(port => 160);
1 голос
/ 15 ноября 2009

Похоже, вы хотите сделать что-то вроде следующего:

Ваш веб-демон CGI будет выглядеть примерно так: (не проверено)

use CGI;
my $cgi = new CGI;
if ($cgi->param('action') eq "MyFirstCommand") {
    # perform your actions for this command and output a response to STDOUT
}
elsif ($cgi->param('action') eq "MySecondCommand") {
    # perform your actions for this command and output a response to STDOUT
}

И ваш сценарий, который вызывает веб-демон CGI, будет составлять URL-адрес для вызова демона таким образом: (опять же, Not Tested)

use LWP::Simple;
my $URL = 'http://hostname:port/cgi-bin/daemon-script.cgi?action=MyFirstCommand';
my $http_response = LWP::Simple::get($URL);
# analyze the response for success or failure
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...