Laravel 版本 8.9.0 Websockets:获取传递给 Pusher\Pusher::trigger() 的参数 4 必须是数组类型,给定 null

问题描述 投票:0回答:1

从 Laravel Websockets 仪表板发送消息时出现此错误。 Laravel 版本是 8.9.0

这就是我的composer.json 文件的样子:

`{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.4",
        "ext-curl": "*",
        "ext-dom": "*",
        "ext-fileinfo": "*",
        "ext-json": "*",
        "ext-libxml": "*",
        "ext-pdo": "*",
        "ext-posix": "^7.3",
        "ext-zip": "*",
        "adoy/oauth2": "1.3.0",
        "beyondcode/laravel-websockets": "^1.13",
        "curl/curl": "2.2.0",
        "doctrine/dbal": "2.3.5",
        "facade/ignition": "^2.3.6",
        "fideloper/proxy": "^4.0",
        "guzzlehttp/guzzle": "^7.0",
        "intervention/image": "^2.4",
        "intervention/imagecache": "^2.3",
        "laravel/framework": "v8.9.0",
        "laravel/horizon": "v5.0",
        "laravel/passport": "^10.1",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^3.0",
        "league/flysystem": "^1.0",
        "maatwebsite/excel": "^3.1",
        "php-ai/php-ml": "^0.9.0",
        "phpmailer/phpmailer": "^6.4",
        "predis/predis": "v1.1.6",
        "pusher/pusher-php-server": "^7.2",
        "spatie/laravel-permission": "^4.2",
        "tightenco/ziggy": "^1.4"
    },
    "require-dev": {
        "filp/whoops": "^2.0",
        "laravel/sail": "^1.5",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^4.1",
        "omniphx/forrest": "2.*",
        "phpunit/phpunit": "^9.0"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "platform": {
            "ext-pcntl": "7.4",
            "ext-posix": "7.4"
        }
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ],
        "post-update-cmd": [
            "@php artisan horizon:publish --ansi"
        ]
    }
}


Hallo

    

.env 中的Broadcast_Driver 是推送器。我的 Broadcasting.php 有这个推送器设置:

'pusher' => [
    'driver' => 'pusher',
    'key' => env('PUSHER_APP_KEY'),
    'secret' => env('PUSHER_APP_SECRET'),
    'app_id' => env('PUSHER_APP_ID'),
    'options' => [
        'cluster' => env('PUSHER_APP_CLUSTER'),
        'encrypted' => true,
        'host' => '127.0.0.1',
        'port' => 6001,
        'scheme' => 'https',
       'curl_options' => [
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
        ]
    ],
],

我的 websockets.php

<?php

use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize;

return [

    /*
     * Set a custom dashboard configuration
     */
    'dashboard' => [
        'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
    ],

    /*
     * This package comes with multi tenancy out of the box. Here you can
     * configure the different apps that can use the webSockets server.
     *
     * Optionally you specify capacity so you can limit the maximum
     * concurrent connections for a specific app.
     *
     * Optionally you can disable client events so clients cannot send
     * messages to each other via the webSockets.
     */
    
    'apps' => [
        [
            'id' => env('PUSHER_APP_ID'),
            'name' => env('APP_NAME'),
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'enable_client_messages' => false,
            'enable_statistics' => false,
            'encrypted' => true,
        ],
    ],
    'ssl' => [
        'local_cert' => '/etc/letsencrypt/live/contento-demo2.net/fullchain.pem',
        'local_pk' => '/etc/letsencrypt/live/contento-demo2.net/privkey.pem',
        'passphrase' => null,
        'verify_peer' => false,
    ],

    /*
     * This class is responsible for finding the apps. The default provider
     * will use the apps defined in this config file.
     *
     * You can create a custom provider by implementing the
     * `AppProvider` interface.
     */
    'app_provider' => BeyondCode\LaravelWebSockets\Apps\ConfigAppProvider::class,

    /*
     * This array contains the hosts of which you want to allow incoming requests.
     * Leave this empty if you want to accept requests from all hosts.
     */
    'allowed_origins' => [
        //
    ],

    /*
     * The maximum request size in kilobytes that is allowed for an incoming WebSocket request.
     */
    'max_request_size_in_kb' => 250,

    /*
     * This path will be used to register the necessary routes for the package.
     */
    'path' => 'laravel-websockets',

    /*
     * Dashboard Routes Middleware
     *
     * These middleware will be assigned to every dashboard route, giving you
     * the chance to add your own middleware to this list or change any of
     * the existing middleware. Or, you can simply stick with this list.
     */
    'middleware' => [
        'web',
        Authorize::class,
    ],

    'statistics' => [
        /*
         * This model will be used to store the statistics of the WebSocketsServer.
         * The only requirement is that the model should extend
         * `WebSocketsStatisticsEntry` provided by this package.
         */
        'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class,

        /**
         * The Statistics Logger will, by default, handle the incoming statistics, store them
         * and then release them into the database on each interval defined below.
         */
        'logger' => BeyondCode\LaravelWebSockets\Statistics\Logger\HttpStatisticsLogger::class,

        /*
         * Here you can specify the interval in seconds at which statistics should be logged.
         */
        'interval_in_seconds' => 60,

        /*
         * When the clean-command is executed, all recorded statistics older than
         * the number of days specified here will be deleted.
         */
        'delete_statistics_older_than_days' => 60,

        /*
         * Use an DNS resolver to make the requests to the statistics logger
         * default is to resolve everything to 127.0.0.1.
         */
        'perform_dns_lookup' => false,
    ],

    /*
     * Define the optional SSL context for your WebSocket connections.
     * You can see all available options at: http://php.net/manual/en/context.ssl.php
     */

/*    'ssl' => [
        'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),
        'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),
        'passphrase' => env('LARAVEL_WEBSOCKETS_SSL_PASSPHRASE', null),
        'verify_peer' => false,
    ],*/

    /*
     * Channel Manager
     * This class handles how channel persistence is handled.
     * By default, persistence is stored in an array by the running webserver.
     * The only requirement is that the class should implement
     * `ChannelManager` interface provided by this package.
     */
    'channel_manager' => \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager::class,
];


错误发生在调用 Pusher->trigger 后,而有效负载中的套接字变量为空:

    
/**
 * Broadcast the given event.
 *
 * @param  array  $channels
 * @param  string  $event
 * @param  array  $payload
 * @return void
 *
 * @throws \Illuminate\Broadcasting\BroadcastException
 */
public function broadcast(array $channels, $event, array $payload = [])
{
    $socket = Arr::pull($payload, 'socket');

    $response = $this->pusher->trigger(
        $this->formatChannels($channels), $event, $payload, $socket, true
    );

    if ((is_array($response) && $response['status'] >= 200 && $response['status'] <= 299)
        || $response === true) {
        return;
    }

    throw new BroadcastException(
        ! empty($response['body'])
            ? sprintf('Pusher error: %s.', $response['status'])
            : 'Failed to connect to Pusher.'
    );
}


我已经知道,Laravel 7.x 版本中有一个错误,所以这方面的任何提示都没有帮助。

热烈欢迎任何帮助,我已经花了 2 天的时间来解决这个问题,我需要一个解决方案。

php laravel laravel-websockets
1个回答
0
投票

通过将 Pusher php 服务器降级到版本 5.0.1 修复了错误:

作曲家需要 Pusher/pusher-php-server ^5.0.1

并遵循 github 上的这些说明:

我遇到了同样的问题,在解决方法之后,我通过将推送器恢复到原始状态并创建新的解决方法来解决它:

从laravel 8调用Pusher.php的触发函数时,我遇到三个问题

这是第 112 行:在...Illuminate/Broadcasting..../PusherBroadcaster.php

$response = $this->pusher->trigger(
$this->formatChannels($channels), $event, $payload, $socket, true
);

问题是

  1. $socket 设置为 null 而不是数组,

  2. laravel 将 $already_encoded 变量设置为 true,但将数据发送为 array not json 我不明白为什么,参数设置为数组 但无论如何将 true 发送给函数。

  3. 函数仅返回正文而不是完整响应

我避免更改 laravel PusherBroadcaster,因此我更改了 Pusher.php 以纠正该问题:

我的解决方法是这样的:

1- Pusher.php 的第 496 行 更改自:

$data_encoded = $this->crypto->encrypt_payload($channels[0], $already_encoded ? $data : json_encode($data));

致:

$data_encoded = $this->crypto->encrypt_payload($channels[0], $already_encoded && !is_array( $data) ? $data : json_encode($data));

Pusher.php第499行 更改自:

$data_encoded = $already_encoded ? $data : json_encode($data);

致:

$data_encoded = $already_encoded && !is_array( $data) ? $data : json_encode($data);

Pusher.php 的第 2 行 518 更改自:

$all_params = array_merge($post_params, $params);

致:

$all_params = array_merge($post_params, is_array($params) ? $params:[]);

3-Pusher.php 的第 542 行 更改自:

return $result;

致:

return $response;

使用它对我有用,并且我在浏览器上收到消息。

非常感谢lisandrop05!

https://github.com/pusher/pusher-http-php/issues/288#issuecomment-787487210

© www.soinside.com 2019 - 2024. All rights reserved.