简体   繁体   English

Symfony 信使 - 序列化消息中的对象

[英]Symfony messenger - serialize objects inside message

Hi I have applications that is dispatching commands(messages) to Amazon SQS queues.您好,我有一些应用程序正在向 Amazon SQS 队列发送命令(消息)。 I have working environment and my commands are in the queue, but in the wrong format like this:我有工作环境,我的命令在队列中,但格式错误,如下所示:

{ "Messages": [ { "MessageId": "f3373e0d-b47e-2a46-51d8-38dc1ee8f07e", "ReceiptHandle": "dzpfgjsnrkwzmzzvzvddepxfpmxwipviybehoedxeolvbndunmceerozsanhwennjvgeunbsfxfxrrywrlkpeuifcnggnslzfgpkilnrwnlyegkcmlaowvcikxhsisujptanjrboedurezuzihngpfmsyxxzmtqghqyrfyycthxuamqnxblprvbbo", "MD5OfBody": "6a69c6c1e53718f891a409e5a9ba98a4", "Body": "O:36:\"Symfony\\Component\\Messenger\\Envelope\":2:{s:44:\"\0Symfony\\Component\\Messenger\\Envelope\0stamps\";a:1:{s:46:\"Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\";a:1:{i:0;O:46:\"Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\":1:{s:55:\"\0Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\0busName\";s:21:\"messenger.bus.default\";}}}s:45:\"\0Symfony\\Component\\Messenger\\Envelope\0message\";O:29:\"App\\Message\\CreatePostCommand\":1:{s:17:\"\0*\0postDataObject\";O:29:\"App\\DataObject\\PostDataObject\":5:{s:5:\"title\";s:11:\"Lorem ipsum\";s:7:\"excerpt\";s:27:\"Lorem ipsum dolor sit amet.\";s:7:\"content\";s:495:\"Donec laoreet maximus l { "Messages": [ { "MessageId": "f3373e0d-b47e-2a46-51d8-38dc1ee8f07e", "ReceiptHandle": "dzpfgjsnrkwzmzzvzvddepxfpmxwipviybehoedxeolvbndunmceerozsanhwennjvgeunbsfxfxrrywrlkpeuifcnggnslzfgpkilnrwnlyegkcmlaowvcikxhsisujptanjrboedurezuzihngpfmsyxxzmtqghqyrfyycthxuamqnxblprvbbo", "MD5OfBody": "6a69c6c1e53718f891a409e5a9ba98a4", "Body": "O:36:\" Symfony\\Component\\Messenger\\Envelope\":2:{s:44:\"\0Symfony\\Component\\Messenger\\Envelope\0stamps\";a:1:{s:46:\"Symfony \\Component\\Messenger\\Stamp\\BusNameStamp\";a:1:{i:0;O:46:\"Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\":1:{s :55:\"\0Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\0busName\";s:21:\"messenger.bus.default\";}}}s:45:\"\0Symfony\ \Component\\Messenger\\Envelope\0message\";O:29:\"App\\Message\\CreatePostCommand\":1:{s:17:\"\0*\0postDataObject\";O:29: \"App\\DataObject\\PostDataObject\":5:{s:5:\"title\";s:11:\"Lorem ipsum\";s:7:\"摘录\";s:27: \"Lorem ipsum dolor sit amet.\";s:7:\"content\";s:495:\"Donec laoreet maximus l acus, nec lacinia risus rutrum vitae. acus,nec lacinia risus rutrum vitae。 Morbi tortor sapien, ornare in congue ac, aliquam quis felis. Morbi tortor sapien, ornare in congue ac, aliquam quis felis。 Pellentesque venenatis, elit eget vehicula viverra, elit lacus congue ante, et accumsan est arcu vitae purus. Pellentesque venenatis, elit eget vehicula viverra, elit lacus congue ante, et accumsan est arcu vitae purus. Aliquam erat volutpat. Aliquam erat volutpat。 Nullam rhoncus risus augue, ut rhoncus leo sollicitudin sed. Maecenas fringilla, metus pretium tristique sodales, sem ante condimentum massa, a facilisis ligula lacus quis purus. Nullam rhoncus risus augue, ut rhoncus leo sollicitudin sed. Maecenas fringilla, metus pretium tristique sodales, sem ante condimentum massa, a facilisis ligula lacus quis purus. Vestibulum pharetra rutrum velit, in rutrum mi mollis vitae.\";s:6:\"author\";s:14:\"Bartosz Belski\";s:12:\"published_at\";N;}}}", "Attributes": { "SenderId": "AIDAIT2UOQQY3AUEKVGXU", "SentTimestamp": "1649947456026" } } ] } Vestibulum pharetra rutrum velit,在 rutrum mi mollis vitae.\";s:6:\"author\";s:14:\"Bartosz Belski\";s:12:\"published_at\";N;}}} ", "Attributes": { "SenderId": "AIDAIT2UOQQY3AUEKVGXU", "SentTimestamp": "1649947456026" } } ] }

I suspect that this is fault of serialization.我怀疑这是序列化的错误。 I want to store it as a json inside the queue.我想将它作为 json 存储在队列中。 But I have no idea how to accomplish this.但我不知道如何做到这一点。

My Command(message):我的命令(消息):

final class CreatePostCommand
{
    protected PostDataObject $postDataObject;

    public function __construct(PostDataObject $postDataObject)
    {
        $this->postDataObject = $postDataObject;
    }

    public function getPostDataObject(): PostDataObject
    {
        return $this->postDataObject;
    }

    public function setPostDataObject(PostDataObject $postDataObject): self
    {
        $this->postDataObject = $postDataObject;

        return $this;
    }
}

My PostDataObject:我的 PostDataObject:

class PostDataObject extends DataObject
{
    public $title;

    public $excerpt;

    public $content;

    public $author;

    public $published_at;
}

There are two methods to implement __serialize and __unserialize .有两种方法可以实现__serialize__unserialize Using them convert to/from json in format that you want:使用它们以您想要的格式转换为 json 或从 json 转换:

final class CreatePostCommand
{
    protected PostDataObject $postDataObject;

    public function __serialize(): array
    {
        return ['title' => $this->postDataObject->title, 'excerpt' => $this->postDataObject->excerpt, ...];
    }

    public function __deserialize(array $data): void
    {
        $this->postDataObject->title = $data['title'];
        $this->postDataObject->excerpt = $data['excerpt'];
        ...
    }
}

my solution was a bit different than what @Justinas proposed.我的解决方案与@Justinas 提出的有点不同。 I created my own serializer for symfony messenger like in this tutorial :我在本教程中为 symfony Messenger 创建了自己的序列化程序:

My code:我的代码:

namespace App\Message\Serializers;

use App\DataObject\PostDataObject;
use App\Message\CreatePostCommand;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;

class JsonDataObjectCommandSerializer implements SerializerInterface
{
    private \Symfony\Component\Serializer\SerializerInterface $serializer;

    public function __construct(\Symfony\Component\Serializer\SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
    }

    public function decode(array $encodedEnvelope): Envelope
    {
        $body = $encodedEnvelope['body'];
        $headers = $encodedEnvelope['headers'];
        $data = json_decode($body, true);
        $message = new CreatePostCommand(new PostDataObject($data));
        $stamps = [];
        if (isset($headers['stamps'])) {
            $stamps = json_decode($headers['stamps']);
        }
        dump($data, $message, $stamps);
        return new Envelope($message, $stamps ?? []);
    }

    public function encode(Envelope $envelope): array
    {
        $message = $envelope->getMessage();
        if ($message instanceof CreatePostCommand) {
            $data = $message->getPostDataObject()->toArray();
        } else {
            throw new \Exception('Unsupported message class');
        }
        $allStamps = [];
        foreach ($envelope->all() as $stamps) {
            $allStamps = array_merge($allStamps, $stamps);
        }

        return [
            'body' => json_encode($data),
            'headers' => [
                'stamps' => $this->serializer->serialize($allStamps, 'json')
            ]
        ];
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM