External session
Материал из Eludia.
Содержание |
Данная функция — конструктор объекта (лёгкой обёртки над LWP::UserAgent), позволяющий одному Eludia-приложению осуществлять удалённый вызов процедур (RPC) другого Eludia-приложения.
Во избежание путаницы, заметим, что Eludia.pm содержит ещё один RPC-механизм: Peering. В данный момент он не документирован. Обозначим различия:
- Peering требует, чтобы оба приложения были доступны друг для друга по HTTP(S), а external_session — только чтобы было доступно вызываемое приложение.
- Peering устанавливает доверие на уровне инсталляций в целом (сервер верит серверу) и копирует в вызываемое приложение информацию о текущем пользователе, а external_session использует для авторизации в вызываемом приложении обычную учётную запись его пользователя.
Инициализация
Единственный параметр, который требуется для создания external_session — HTTP(S)-адрес вызываемого приложения:
my $external_session = external_session ($system_params -> {host});
Кроме того, 2-м параметром можно задать опции, передаваемые LWP::UserAgent:
my $external_session = external_session ($system_params -> {host}, {timeout => 10});
Соглашения о вызовах
Все методы объекта, создаваемого external_session, возвращают undef в в случае успеха и сообщение об ошибке в противном случае. Это же сообщение доступно в качестве значения компоненты {error}. Таким образом, external_session удобно использовать в валидаторах следующим образом:
$external_session -> something (...) and return $external_session -> {error};
Собственно результаты удалённого вызова можно извлечь из компонент объекта, это показано ниже.
Авторизация
Для установления сессии предназначен метод login:
$external_session -> login ({
login => $system_params -> {login},
password => $system_params -> {password},
}) and return $external_session -> {error};
В случае успеха полученный номер сессии запоминается в объекте (компонента {sid}) и используется при всех дальнейших вызовах.
Помимо login и password, можно передавать иные параметры, требуемые на login-форме вызываемого приложения. Скажем, там может понадобиться номер сервера авторизации.
Вообще метод login в основном сводится к вызову описанного ниже более универсального метода query с предустановленными значениями параметров type='logon' и action='execute'. При необходимости их можно переопределить.
Вызовы процедур
Итак, опишем основной метод данного RPC-механизма: query. Обычно он вызывается с единственным аргументом: набором параметров запроса:
$external_session -> query ({
type => 'sync_exports',
id => $id,
action => 'update',
_file => [$data -> {file_path}],
}) and return $external_session -> {error};
Параметр-ссылка на массив описывает файл, в соответствии с соглашениями, принятыми в HTTP::Request::Common.
Вызовы-действия
Результатом успешного действия в Eludia.pm, как правило, является перенаправление на некоторый URL. Точнее, на URL с тем же базовым адресом, что у исходного вызова, но с новым набором параметров.
Этот набор параметров, доступный в виде компоненты {url_params}, можно использовать как результат вызова. Например, результатом действия create обычно является создание новой fake-записи. Её id можно узнать следующим образом:
$external_session -> query ({
type => 'sync_exports',
action => 'create',
}) and return $external_session -> {error};
my $id = $external_session -> {url_params} -> {id};
Вызовы-просмотры
Вызов удалённой процедуры может использоваться не только для изменения данных, но просто для их извлечения. В таком случае результат Content-процедуры (select_$type или get_item_of_$type) доступен в виде компоненты {content}:
$external_session -> query ({
type => 'sync_exports_alien',
}) and return $external_session -> {error};
my $sync_exports = $external_session -> {content} -> {sync_exports}
or return 'Сервер вернул некорректный ответ';
@$sync_exports > 0 or return 'Свежих обновлений нет.';
ВНИМАНИЕ! По соображениям компьютерной так называемой "безопасности", данный механизм работоспособен только в том случае, если для содержимого установлена волшебная компонента:
$data -> {__this_content_is_ok_to_be_shown_completely} = 1;
Таким образом разработчик вызываемого приложения подписывается за то, что прямое чтение исходных данных текущей экранной формы не может привести к разглашению секретных данных.
Копирование файлов
А как быть в том случае, если требуется получить бинарный, файловый HTTP-ответ? Для этого можно воспользоваться 2-м параметром query, который имеет тот же смысл, что 2-й параметр LWP::UserAgent::request: либо абсолютный путь файла, либо callback-функция для обработки содержимого (без заголовков).
Специально для сохранения файлов, генерируемых вызываемым приложением, предусмотрен метод download:
$external_session -> download ({
type => 'sync_exports_alien',
id => $sync_exports -> [0] -> {id},
action => 'download',
}) and return $external_session -> {error};
В случае успеха информация о загруженном файле доступна в виде компоненты {file}, имеющей точно тот же вид, как результат upload_file.
