Laravel 跨框架队列交互
公司大部分项目是laravel框架,但有些是yii框架,这两个框架之间有消息需要通信,比如在yii框架发布消息,laravel框架中的队列去处理,用redis作为消息连接纽带
laravel 队列原理是将类实例化后再序列化存到redis中(序列化的类只存储属性值)。消费的时候直接反序列化得到类和属性值再去相应的类中找到方法执行
直接上代码
lavavel 消费类
<?php namespace App\Jobs; class TestJob extends BaseJob{ public $receipt; public $queue = "receipt-to-stock";//定义队列名称 和生产队列中的queue保持一致
public function handle() {
\Log::debug("收到队列信息:", $this->receipt);
}
public function failed(){
\Log::info("队列执行失败");
}
}
yii 生产类
<?php namespace App\Jobs; class TestJob extends BaseJob{ private $receipt; public $queue = "receipt-to-stock"; //定义队列名称 和消费中的queue保持一致 /** * @param array $receipt 单据 */ public function __construct(array $receipt=[]) { $this->receipt = $receipt; } }
yii 封装序列化方法
$receipt 是要处理的数据
$jobName 是消费和生产的类名如 "App\\Jobs\\TestJob" 两者保持一致,如果不一致请适当调整下面的代码
public function serializeForLaravelQueue($receipt, $jobName) { $result = [ "displayName" => $jobName,//消费的类名 "job" => "Illuminate\Queue\CallQueuedHandler@call", "maxTries" => null, "timeout" => null, "timeoutAt" => null, "id" => time(), "attempts" => 0, "type" => "job", "tags" => [], "pushedAt" => time(), "data" => [ 'commandName' => $jobName,//消费的类名 'command' => serialize(new $jobName($receipt))//生产的类名 ] ]; return json_encode($result, JSON_UNESCAPED_UNICODE); }
调用
$data = serializeForLaravelQueue(["hello world"], "App\\Jobs\\TestJob");
$redis->LPUSH("queues:receipt-to-stock", $data);//将序列化的类写入redis的List中
这个时候在yii框架中发布消息,laravel项目就会自动处理了!
注意事项:
1、确保redis在同一个库中
2、队列名保持一致,也就是redis中存储的key值