Асинхронні виклики

This page has not been translated yet, showing the version in: UK.

Асинхронні виклики

Ця сторінка описує версію 5.x. Опис для 4.x — у перемикачі версій угорі сторінки.

Асинхронний клас (AsyncUserSDK) не чекає відповіді: він кладе JSON-RPC запит у чергу, звідки його забирає сервер на JsonRpcBundle (Асинхронність). Метод одразу повертає true. Результат, якщо потрібен, сервер надсилає на callback.

Що потрібно на сервері

  • Асинхронний транспорт у ufo_json_rpc.async, назва якого починається з rpc_async (наприклад, rpc_async), і споживач messenger:consume.
  • docs.async_dsn_info: true — інакше транспорт не потрапить у документацію, і SDK не згенерує асинхронних класів.

Підключення

Транспорт вибирається за схемою DSN серед зареєстрованих resolver-ів. Для RabbitMQ встановіть AMQP-реалізацію:

composer require ufo-tech/component-transport-amqp   # потрібне розширення ext-amqp
use App\Sdk\Orders\AsyncUserSDK;
use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpTransportFactory;
use Ufo\Component\AsyncAmqpTransport\AMQPTransportResolver;
use Ufo\Component\TransportContracts\AsyncTransportFactory;

$transports = new AsyncTransportFactory([
    new AMQPTransportResolver(new AmqpTransportFactory()),
]);

$users = new AsyncUserSDK(
    asyncTransportFactory: $transports,
    token: $token,                 // перевіряється сервером так само, як для HTTP
    secretAsync: 'user:password',  // підставляється в {rpc_async_secret} у DSN
    transportName: 'rpc_async',    // ключ DSN у sdk_config.yaml
);

$users->rename(5, 'John');         // true — запит у черзі

DSN береться з sdk_config.yaml(.dist): amqp://{rpc_async_secret}@rabbit.example.com:5672/vhost/rpc. Плейсхолдер {<transportName>_secret} замінюється на secretAsync, тож облікові дані брокера не зберігаються у файлі.

AMQP-resolver підтримує схеми amqp і amqps, публікує в exchange queue_exchange (тип direct) з назвою черги й ключем маршрутизації з останнього сегмента DSN і позначає повідомлення як persistent. Повідомлення серіалізується PhpSerializer, тож транспорт сервера має використовувати сумісний серіалізатор (стандартний у Symfony Messenger).

Додаткові методи

Метод Що робить
callbackTo(string $url) $rpc.callback — сервер надішле результат POST-запитом на URL
asyncTimeout(int $seconds) $rpc.timeout
withMeta(array $meta) Метадані повідомлення (RpcAsyncRequest::$meta)
rayId(), withoutCache(), withCache() Як у синхронних класах
$reports->callbackTo('https://my-app.example.com/rpc-callback')->build($month);

Асинхронні класи не скидають спеціальні параметри і не змінюють id після виклику: callbackTo() чи asyncTimeout() діють на всі наступні виклики того самого об'єкта. Не викликайте ping() на асинхронному класі. Див. Актуальні помилки.

Групи API

Асинхронний запит надсилається без групи, тож сервер виконує його в групі general. Методи інших груп API асинхронно через SDK не викликати.

Власний транспорт

Реалізуйте Ufo\Component\TransportContracts\AsyncTransportResolverInterface або успадкуйте AbstractAsyncTransportResolver:

interface AsyncTransportResolverInterface
{
    public function getTransportFactory(): TransportFactoryInterface;
    public function getTransport(string $dsn): TransportInterface;
    public function createAsyncStamp(AsyncStampDTO $asyncStampData): StampInterface;
    public function getSupportSchemes(): array;   // наприклад ['kafka']
}

і додайте його в AsyncTransportFactory. Немає resolver-а для схеми DSN — TransportNotFoundException.