【问题标题】:Laravel dispatch plain json on queueLaravel 在队列上调度纯 json
【发布时间】:2019-03-27 15:27:50
【问题描述】:

我总共有 2 个简单的问题。我目前正在研究 Laravel 中的一些事件处理,并希望使用 RabbitMQ 作为我的事件存储。因此我安装了这个包开始:https://github.com/php-enqueue/enqueue-dev

首先我注册了它,我可以将消息推送到 RabbitMQ:

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

但问题是 Laravel 将某种格式推送到队列中,我不知道如何更改它。示例消息是:

{
    "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;}"
    }
}

所以问题是,我该如何改变呢?主要原因是消费者端甚至不是PHP应用程序,也无法解释PHP序列化模型。因此,我正在寻找一种方法来推送纯 JSON 对象。

另一方面,我也想了解如何构建自定义侦听器?对于听众来说,同样的事情也会发生。 Laravel 尝试读取该方法,但是当我推送纯 JSON 时,这将永远无法工作。有没有办法在主题上注册处理程序并在处理程序本身内进一步处理消息的有效负载?

【问题讨论】:

  • 类似dispatch(deserialize($job->getData()))
  • Dispatch 需要一个对象。反序列化不是有效的 php 函数,作业没有可用的 getData 方法?
  • 另一个要考虑的选项,因为 Laravel 队列基础设施的主要目的是让 Laravel 发送和处理作业,直接使用 php-amqplib。然后,您可以完全控制推送到队列中的内容。
  • 根据您的语言,有一些库可以反序列化由 PHP 的序列化函数创建的内容:npmjs.com/package/php-unserialize

标签: php laravel queue


【解决方案1】:

有一个 laravel-queue 库与您链接的 php-enqueue 库一起使用,使其与 Florian 提到的 Laravel's built in queue system 兼容。

默认情况下,它仍然会使用序列化对象,但我认为可以覆盖它。如果你在核心 Laravel 框架中查看 Queue.php, createObjectPayload() on line 130,那是作业被序列化的地方。

如果你在 laravel-queue 库中扩展 Queue 类,你应该能够将 createObjectPayload 更改为如下所示:

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),
        ],
    ]);
}

这应该对作业数据进行 JSON 编码,而不是对其进行序列化。您甚至可以完全删除编码,因为我认为它已经在链上某处进行了 JSON 编码。

【讨论】:

  • 似乎有点逻辑,让我尝试实现一些东西。我假设侦听器也是如此(如果我会在 PHP 中构建一些东西,对吗?)因为在这种情况下,默认情况下需要特定的消息格式,这是 Laravel 特定的
  • @Dirkos 如果你的监听器是用 PHP 构建的,你就可以使用 serialize 函数,所以这不是问题,对吧?如果您使用的是非 PHP 侦听器,那么无论如何您都是从头开始编写的。
  • 是的,最初它会是 PHP,但稍后会被翻译成其他语言。老实说,我也不太喜欢将我的队列绑定到特定的框架实现,所以猜猜现在马上解耦它很好
  • @Dirkos 在这种情况下,如果您确认某些链接我的答案将起作用,请考虑保留序列化格式,直到您决定切换到非 PHP 处理器。这将允许你现在使用完整的 Laravel Queue 基础设施,然后在你准备好切换时重写 Queue 类。
【解决方案2】:

有一种简单的方法可以满足您的目的: 先为rabbit安装这个包:

vladimir-yuldashev/laravel-queue-rabbitmq

在控制器中:

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

您可以生成json 并输入此命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 2018-06-18
    • 2018-03-15
    • 2019-07-02
    • 2019-09-13
    相关资源
    最近更新 更多