Laravel Queue反序列化问题

时间:2016-01-09 22:14:30

标签: php laravel serialization push-notification laravel-5

我很难弄清楚我的Laravel应用程序究竟发生了什么。它在本地功能齐全(Mac,php 5.5.26),所以我一直在通过伪造(php 5.6.15)在我的数字海洋液滴上测试应用程序。

我正在使用this package将推送通知发送到使用我的Laravel api的前端应用程序。为了使api调用更快,我将推送通知委托给在本地工作得很好的Laravel队列,但是当我在数字海洋上测试时,我收到了这个错误。

[2016-01-09 20:34:09] stage.ERROR: exception 'ErrorException' with message 'Erroneous data format for unserializing 'ArrayIterator'' in {path}/{project}/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php:74

我正在使用数据库驱动程序。这是我本地数据库作业表中的序列化作业行...

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"command":"O:28:\"App\\Jobs\\Push\\SendPushFollow\":4:{s:34:\"\u0000App\\Jobs\\Push\\SendPushFollow\u0000push\";O:27:\"App\\Helpers\\Push\\PushFollow\":5:{s:14:\"\u0000*\u0000ios_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";C:13:\"ArrayIterator\":21:{x:i:0;a:0:{};m:a:0:{}}}s:16:\"\u0000*\u0000android_count\";i:2;s:12:\"\u0000*\u0000ios_count\";i:0;s:18:\"\u0000*\u0000android_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";C:13:\"ArrayIterator\":953:{x:i:0;a:2:{s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";s:13:\"\u0000*\u0000parameters\";a:0:{}}s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";s:13:\"\u0000*\u0000parameters\";a:0:{}}};m:a:0:{}}}s:10:\"\u0000*\u0000message\";O:36:\"Sly\\NotificationPusher\\Model\\Message\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Message\u0000text\";s:32:\"John Smith is now following you!\";s:10:\"\u0000*\u0000options\";a:12:{s:5:\"badge\";i:1;s:5:\"sound\";s:12:\"example.aiff\";s:12:\"actionLocKey\";s:20:\"Action button title!\";s:6:\"locKey\";s:13:\"localized key\";s:7:\"locArgs\";a:2:{i:0;s:14:\"localized args\";i:1;s:14:\"localized args\";}s:11:\"launchImage\";s:9:\"image.jpg\";s:5:\"title\";s:21:\"InMyBag: New Follower\";s:6:\"custom\";a:0:{}s:5:\"notId\";i:7;s:5:\"style\";s:5:\"inbox\";s:8:\"ledColor\";a:4:{i:0;i:0;i:1;i:0;i:2;i:255;i:3;i:0;}s:16:\"vibrationPattern\";a:3:{i:0;i:500;i:1;i:250;i:2;i:500;}}}}s:5:\"queue\";N;s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}}

这是服务器表中的行条目......

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"command":"O:28:\"App\\Jobs\\Push\\SendPushFollow\":4:{s:34:\"\u0000App\\Jobs\\Push\\SendPushFollow\u0000push\";O:27:\"App\\Helpers\\Push\\PushFollow\":5:{s:14:\"\u0000*\u0000ios_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";O:13:\"ArrayIterator\":0:{}}s:16:\"\u0000*\u0000android_count\";i:2;s:12:\"\u0000*\u0000ios_count\";i:0;s:18:\"\u0000*\u0000android_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";O:13:\"ArrayIterator\":2:{s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";s:13:\"\u0000*\u0000parameters\";a:0:{}}s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";s:13:\"\u0000*\u0000parameters\";a:0:{}}}}s:10:\"\u0000*\u0000message\";O:36:\"Sly\\NotificationPusher\\Model\\Message\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Message\u0000text\";s:32:\"John Smith is now following you!\";s:10:\"\u0000*\u0000options\";a:12:{s:5:\"badge\";i:1;s:5:\"sound\";s:12:\"example.aiff\";s:12:\"actionLocKey\";s:20:\"Action button title!\";s:6:\"locKey\";s:13:\"localized key\";s:7:\"locArgs\";a:2:{i:0;s:14:\"localized args\";i:1;s:14:\"localized args\";}s:11:\"launchImage\";s:9:\"image.jpg\";s:5:\"title\";s:21:\"InMyBag: New Follower\";s:6:\"custom\";a:0:{}s:5:\"notId\";i:10;s:5:\"style\";s:5:\"inbox\";s:8:\"ledColor\";a:4:{i:0;i:0;i:1;i:0;i:2;i:255;i:3;i:0;}s:16:\"vibrationPattern\";a:3:{i:0;i:500;i:1;i:250;i:2;i:500;}}}}s:5:\"queue\";N;s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}}

我运行了一个在线文本dif,发现该blob的序列化数据部分在ArrayIterator部分中发生了一些差异(如指出的错误日志)。看起来差异来自PushNotification :: DeviceCollection对象序列化的方式在我的本地机器和服务器之间是不同的。在我的测试中,我在本地和服务器上使用相同的POST数据命中api端点,以确保序列化的输出应该相同,但它不是。

我不确定如何解决这个问题。我不知道这在技术上是否是PushNotification包的错误(我没有看到任何与此问题相关的错误报告),或者它是否只是我正在掩饰的其他内容。

另外,在旁注中,我正在使用另一个队列来发送KeenIO事件,使用与此Push结构类似的类结构,并且它没有任何问题所以我真的觉得它是这样的一定是PushNotification包的一个问题...有什么想法吗?

解决

因此事实证明这是PHP版本的问题。我的服务器运行5.6,当我在PHP 7.0上制作另一个Droplet并克隆服务器时,一切都开始工作了。我启动并运行了原始服务器,因此它可以作为使用beanstalkd的推送通知的队列处理器,并且它像冠军一样工作。

修改

我正在使用supervisor来运行queue:work命令。我跑了

php artisan queue:restart

我确保通过命令行执行kill命令运行新测试时,工匠进程完全停止。同样,队列工作者在服务器上的KeenIO作业没有问题,只有PushNotification作业。

这是工作班:

<?php namespace App\Jobs\Push;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Jobs\SendPushEvent;
use App\Helpers\Push\PushFollow;

class SendPushFollow extends SendPushEvent implements SelfHandling, ShouldQueue {
    use InteractsWithQueue, SerializesModels;
    private $push;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($follower, $followee)
    {
        $this->push = new PushFollow($follower, $followee);
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(){
        $this->push->send();
    }
}

这里是PushFollow类,其中包含所有PushNotification逻辑。

<?php namespace App\Helpers\Push;

use PushNotification;
use App\Helpers\Push\Push;
use Log;

class PushFollow extends Push {
    /**
     * This builds the default notification.
     * @param array  $data the passed in data array
     * @param [type] $type android or iOS
     */
    public function __construct ($follower, $followee) {
        $_ios_devices = [];
        $_android_devices = [];
        $this->ios_count = 0;
        $this->android_count = 0;

        foreach($followee->devices as $_device){
            if($_device->platform == "ios"){
                $_ios_devices[] = PushNotification::Device($_device->identifier);
                $this->ios_count++;
            } elseif ($_device->platform == "android") {
                $_android_devices[] = PushNotification::Device($_device->identifier);
                $this->android_count++;
            }
        }

        Log::info('FINISHED BUILDING THE LISTS!!!');

        $this->ios_devices = PushNotification::DeviceCollection($_ios_devices);
        $this->android_devices = PushNotification::DeviceCollection($_android_devices);

        Log::info('SET THE DEVICE COLLECTIONS');

        $this->message = PushNotification::Message($follower->profile->name.' is now following you!',[
            'badge' => 1,
            'sound' => 'example.aiff',
            'actionLocKey' => 'Action button title!',
            'locKey' => 'localized key',
            'locArgs' => array(
                'localized args',
                'localized args',
            ),
            'launchImage' => 'image.jpg',
            'title' => env('APP_NAME').': New Follower',
            'custom' => [],
            'notId' => rand(1, 20),
            'style' => 'inbox',
            /*
            'actions' => [
                ['icon' => "emailGuests", 'title' => "EMAIL GUESTS", 'callback' => "app.emailGuests"],
                [ 'icon' => "snooze", 'title' => "SNOOZE", 'callback' => "app.snooze"],
            ],
            */
            'ledColor' => [0, 0, 255, 0],
            'vibrationPattern' => [500, 250, 500],

        ]);

        Log::info('SET THE MESSAGE');
    }

    public function send () {
        Log::info('CALLING THE SEND METHOD');
        if($this->android_count) {
            PushNotification::app(env('ANDROID_PUSH_NAME'))
                ->to($this->android_devices)
                ->send($this->message);
        }

        if($this->ios_count){
            PushNotification::app(env('IOS_PUSH_NAME'))
                ->to($this->ios_devices)
                ->send($this->message);
        }
    }
}

这里是我所有不同推送类扩展的Push类。

<?php namespace App\Helpers\Push;

abstract class Push {
    protected $ios_devices;
    protected $android_count;
    protected $ios_count;
    protected $android_devices;
    protected $message;
}

哦,这里也是堆栈跟踪。

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'Erroneous data ...', '/home/forge/def...', 74, Array)
#1 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(74): unserialize('O:28:"App\\Jobs\\...')
#2 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(212): Illuminate\Queue\CallQueuedHandler->failed(Array)
#3 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(261): Illuminate\Queue\Jobs\Job->failed()
#4 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\Queue\Worker->logFailedJob('database', Object(Illuminate\Queue\Jobs\DatabaseJob))
#5 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(159): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), '5', 0)
#6 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(111): Illuminate\Queue\Worker->pop(NULL, 'keen,push_notif...', 0, 3, '5')
#7 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(87): Illuminate\Queue\Worker->runNextJobForDaemon(NULL, 'keen,push_notif...', 0, 3, '5')
#8 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(103): Illuminate\Queue\Worker->daemon(NULL, 'keen,push_notif...', 0, 128, 3, '5')
#9 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(71): Illuminate\Queue\Console\WorkCommand->runWorker(NULL, 'keen,push_notif...', 0, 128, true)
#10 [internal function]: Illuminate\Queue\Console\WorkCommand->fire()
#11 {path_to_project}/vendor/laravel/framework/src/Illuminate/Container/Container.php(507): call_user_func_array(Array, Array)
#12 {path_to_project}/vendor/laravel/framework/src/Illuminate/Console/Command.php(150): Illuminate\Container\Container->call(Array)
#13 {path_to_project}/vendor/symfony/console/Command/Command.php(256): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 {path_to_project}/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 {path_to_project}/vendor/symfony/console/Application.php(837): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 {path_to_project}/vendor/symfony/console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#17 {path_to_project}/vendor/symfony/console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#18 {path_to_project}/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(107): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#19 {path_to_project}/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 {main} 

2 个答案:

答案 0 :(得分:1)

因此事实证明这是PHP版本的问题。我的服务器运行5.6,当我在PHP 7.0上制作另一个Droplet并克隆服务器时,一切都开始工作了。我启动并运行了原始服务器,因此它可以作为使用beanstalkd的推送通知的队列处理器,并且它像冠军一样工作。

答案 1 :(得分:0)

很抱歉听到您使用的所有php版本的信息,但是我也经常遇到此问题,而且看来您只需要通过运行以下操作来清除缓存:

php artisan route:cache

在具有Laravel生成的缓存后尝试安装作曲家软件包时,这很常见。