2
votes

Laravel envoie le json ordinaire sur la file d'attente

J'ai 2 questions simples dans l'ensemble. Je suis actuellement à la recherche d'une gestion d'événements à Laravel et j'aimerais utiliser RabbitMQ comme magasin d'événements. C'est pourquoi j'ai installé ce package pour commencer avec: https://github.com/php-enqueue/enqueue -dev

Pour commencer, je l'ai enregistré et je peux envoyer des messages à RabbitMQ:

{
    "job":"Illuminate\\\\Queue\\\\CallQueuedHandler@call",
    "data":{
        "command":"O:29:\\"Acme\\Jobs\\FooJob\\":4:{s:11:\\"fooBar\\";s:7:\\"abc-123\\";s:5:\\"queue\\";N;s:5:\\"delay\\";N;s:6:\\"\\u0000*\\u0000job\\";N;}"
    }
}

Le problème est cependant que Laravel pousse un certain format sur la file d'attente et je ne peux pas comprendre comment changer cela. Un exemple de message serait:

$job = (new Sendemail())->onQueue('email')->onConnection('interop');
dispatch($job);

Alors la question est, comment puis-je changer cela? La raison principale à cela est que le côté consommateur n'est même pas une application PHP qui ne peut pas non plus interpréter le modèle sérialisé PHP. Par conséquent, je cherche un moyen de pousser un objet JSON simple à la place.

D'un autre côté, je voudrais également comprendre comment vous pouvez créer un écouteur personnalisé? Pour l'auditeur, la même chose se produit. Laravel essaie de lire la méthode, mais lorsque je pousse JSON brut, cela ne fonctionnera jamais. N'y a-t-il pas un moyen d'enregistrer un gestionnaire sur un sujet et de gérer davantage la charge utile du message dans le gestionnaire lui-même?


4 commentaires

quelque chose comme dispatch (deserialize ($ job-> getData ()))


L'expédition nécessite un objet. La désérialisation n'est pas une fonction php valide et le travail n'a pas de méthode getData disponible?


Une autre option à considérer, puisque le point principal de l’infrastructure Laravel Queue est que Laravel envoie et traite les travaux en utilisant simplement php-amqplib directement. Vous auriez alors un contrôle total sur ce qui est mis dans la file d'attente.


Selon votre langue, il existe des bibliothèques pour désérialiser quelque chose créé par la fonction de sérialisation de PHP: npmjs.com/package / php-unserialize


3 Réponses :


-1
votes

Avez-vous examiné la solution Laravel pour la gestion des files d'attente et des travaux?

https://laravel.com/docs/5.5/queues

Si oui, quelles sont les raisons de votre autre choix?


1 commentaires

Le natif de Laravel ne prend pas en charge RabbitMQ par exemple ni aucun protocole lié à AMQP. Les autres raisons sont que laravel par défaut pousse une classe de travail complète dans la file d'attente où j'ai besoin d'un objet json simple. Cependant, rien à trouver dans la documentation sur la façon de gérer cela. Dans la mesure où je comprends correctement la documentation, elle est principalement conçue pour gérer les événements internes sur un bus d'événements où je dois publier des événements à un deuxième consommateur écrits dans d'autres langues.



0
votes

Il existe une laravel-queue qui fonctionne avec la bibliothèque php-enqueue que vous lié pour le rendre compatible avec le système de file d'attente intégré de Laravel mentionné par Florian.

Par défaut , il utilisera toujours un objet sérialisé, mais je pense que cela peut être remplacé. Si vous regardez dans Queub ) à la ligne 130 dans le cadre principal de Laravel, c'est là que le travail est sérialisé.

Si vous étendez la classe Queue dans la bibliothèque laravel-queue, vous devriez être en mesure de changer createObjectPayload en ressembler à quelque chose comme ceci:

protected function createObjectPayload($job, $queue)
{
    $payload = $this->withCreatePayloadHooks($queue, [
        'displayName' => $this->getDisplayName($job),
        'job' => 'Illuminate\Queue\CallQueuedHandler@call',
        'maxTries' => $job->tries ?? null,
        'timeout' => $job->timeout ?? null,
        'timeoutAt' => $this->getJobExpiration($job),
        'data' => [
            'commandName' => $job,
            'command' => $job,
        ],
    ]);
    return array_merge($payload, [
        'data' => [
            'commandName' => get_class($job),
            'command' => json_encode(clone $job),
        ],
    ]);
}

Cela devrait JSON encoder les données de travail au lieu de les sérialiser. Vous pourrez peut-être même supprimer complètement l'encodage, car je pense qu'il est déjà encodé en JSON quelque part dans la chaîne.


4 commentaires

Cela semble logique, laissez-moi essayer de mettre en œuvre quelque chose. Je suppose qu'il en va de même pour l'auditeur (si je construisais quelque chose en PHP, n'est-ce pas?) Puisque le fait par défaut attend un certain format de message dans ce cas qui est spécifique à Laravel


@Dirkos Si votre auditeur est construit en PHP, vous pourrez utiliser la fonction de sérialisation, donc ce ne serait pas un problème, non? Si vous utilisez un écouteur non PHP, vous écrivez de toute façon à partir de zéro.


Ouais au départ ce sera PHP mais sera traduit plus tard dans d'autres langues. Je n'aime pas non plus vraiment lier mes files d'attente à des implémentations de framework spécifiques pour être honnête, alors devinez que c'est bien de le découpler maintenant tout de suite


@Dirkos Dans ce cas, si vous confirmez quelque chose de lien, ma réponse fonctionnera, pensez à conserver le format de sérialisation jusqu'à ce que vous décidiez de passer à un processeur non PHP. Cela vous permettra d'utiliser l'infrastructure complète de Laravel Queue pour le moment, puis de remplacer la classe Queue plus tard lorsque vous serez prêt à basculer.



0
votes

Il existe un moyen simple pour votre objectif: Installez d'abord ce package pour rabbit:

Queue::connection('rabbitmq')->pushRaw('{you can generate a json format here}', 'queue_name');

et dans le contrôleur:

vladimir-yuldashev/laravel-queue-rabbitmq

vous pouvez générer un json et mettez cette commande.


0 commentaires