#Laravel Reverb - App key <key> not in this cluster.

9 messages · Page 1 of 1 (latest)

dry frost
#

Hey there, I'm having a bug in my Laravel code with Reverb.

As I try to send a notification with websockets - my logs are telling me my app keys aren't in the cluster. My frontend does connect with my websocket and I get a heartbeat on it. I also run:
php artisan queue:work and php artisan reverb:start. The exact error looks like this:

. {"exception":"[object] (Illuminate\\Broadcasting\\BroadcastException(code: 0): Pusher error: App key <redacted> not in this cluster. Did you forget to specify the cluster?```

My .env looks like this:

BROADCAST_CONNECTION=reverb

...

REVERB_APP_ID=<app_id_genned_by_reverb>
REVERB_APP_KEY=<app_key_genned_by_reverb>
REVERB_APP_SECRET=<app_secret_genned_by_reverb>
REVERB_HOST=<domain_without_scheme>
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_APP_ENV="${APP_ENV}"
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST=<domain_without_scheme>
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"


I wonder if it'll help any - but this is the code that should fire the broadcast event:
```php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\BroadcastMessage;
use App\Models\Flight;
use App\Models\User;

class FlightMarkedForReview extends Notification implements ShouldQueue
{
    use Queueable;

    protected $flight;
    protected $markedBy;

    /**
     * Create a new notification instance.
     */
    public function __construct(Flight $flight, User $markedBy)
    {
        $this->flight = $flight;
        $this->markedBy = $markedBy;
    }

    /**
     * Get the notification's delivery channels.
     */
    public function via($notifiable)
    {
        return ['database', 'broadcast'];
    }

    /**
     * Get the array representation of the notification (for database storage).
     */
    public function toArray($notifiable)
    {
        return [
            'flight_id' => $this->flight->id,
            'marked_by_id' => $this->markedBy->id,
            'marked_by_name' => $this->markedBy->name,
            'message_key' => 'notifications.flight_marked_for_review',
            'message_params' => [
                'id' => $this->flight->id,
                'name' => $this->markedBy->name,
            ],
            'message' => "Flight #{$this->flight->id} has been marked for review by {$this->markedBy->name}",
        ];
    }
}
weary terrace
#

How does your config look like?

dry frost
#
// config/reverb.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Reverb Server
    |--------------------------------------------------------------------------
    |
    | This option controls the default server used by Reverb to handle
    | incoming messages as well as broadcasting message to all your
    | connected clients. At this time only "reverb" is supported.
    |
    */

    'default' => env('REVERB_SERVER', 'reverb'),

    /*
    |--------------------------------------------------------------------------
    | Reverb Servers
    |--------------------------------------------------------------------------
    |
    | Here you may define details for each of the supported Reverb servers.
    | Each server has its own configuration options that are defined in
    | the array below. You should ensure all the options are present.
    |
    */

    'servers' => [

        'reverb' => [
            'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
            'port' => env('REVERB_SERVER_PORT', 8080),
            'path' => env('REVERB_SERVER_PATH', ''),
            'hostname' => env('REVERB_HOST'),
            'options' => [
                'tls' => [],
            ],
            'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
            'scaling' => [
                'enabled' => env('REVERB_SCALING_ENABLED', false),
                'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
                'server' => [
                    'url' => env('REDIS_URL'),
                    'host' => env('REDIS_HOST', '127.0.0.1'),
                    'port' => env('REDIS_PORT', '6379'),
                    'username' => env('REDIS_USERNAME'),
                    'password' => env('REDIS_PASSWORD'),
                    'database' => env('REDIS_DB', '0'),
                ],
            ],
            'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
            'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Reverb Applications
    |--------------------------------------------------------------------------
    |
    | Here you may define how Reverb applications are managed. If you choose
    | to use the "config" provider, you may define an array of apps which
    | your server will support, including their connection credentials.
    |
    */

    'apps' => [

        'provider' => 'config',

        'apps' => [
            [
                'key' => env('REVERB_APP_KEY'),
                'secret' => env('REVERB_APP_SECRET'),
                'app_id' => env('REVERB_APP_ID'),
                'options' => [
                    'host' => env('REVERB_HOST'),
                    'port' => env('REVERB_PORT', 443),
                    'scheme' => env('REVERB_SCHEME', 'https'),
                    'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
                ],
                'allowed_origins' => ['*'],
                'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
                'activity_timeout' => env('REVERB_APP_ACTIVITY_TIMEOUT', 30),
                'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
            ],
        ],

    ],

];
#
// config/broadcasting.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Broadcaster
    |--------------------------------------------------------------------------
    |
    | This option controls the default broadcaster that will be used by the
    | framework when an event needs to be broadcast. You may set this to
    | any of the connections defined in the "connections" array below.
    |
    | Supported: "reverb", "pusher", "ably", "redis", "log", "null"
    |
    */

    'default' => env('BROADCAST_CONNECTION', 'null'),

    /*
    |--------------------------------------------------------------------------
    | Broadcast Connections
    |--------------------------------------------------------------------------
    |
    | Here you may define all of the broadcast connections that will be used
    | to broadcast events to other systems or over WebSockets. Samples of
    | each available type of connection are provided inside this array.
    |
    */

    'connections' => [

        'reverb' => [
            'driver' => 'reverb',
            'app_id' => env('REVERB_APP_ID'),
            'key' => env('REVERB_APP_KEY'),
            'secret' => env('REVERB_APP_SECRET'),
            'host' => env('REVERB_HOST'),
            'port' => env('REVERB_PORT', 443),
            'scheme' => env('REVERB_SCHEME', 'https'),
            'options' => [
                'retry_on_error' => true,
                'retry_wait_time' => 100, // milliseconds
                'retry_multiplier' => 1.2, // increases wait time by 20% on each retry
                'max_retries' => 10,
            ],
        ],

        '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'),
                'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com',
                'port' => env('PUSHER_PORT', 443),
                'scheme' => env('PUSHER_SCHEME', 'https'),
                'encrypted' => true,
                'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
            ],
            'client_options' => [
                // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
            ],
        ],

        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY'),
        ],

        'log' => [
            'driver' => 'log',
        ],

        'null' => [
            'driver' => 'null',
        ],

    ],

];

#

Even when I try to change my key in the .env - the error still occurs with the old key. I thought it might be cache - but nothing changed after clearing the cache

#

but trying to search on the key in my code shows nothing - so it isn't hardcoded.

weary terrace
#

It looks like you are missing some pusher env variables, but you are not using pusher right

dry frost
#

I'm using Laravel Reverb

dry frost
#

I have now changed some config keys - and now I get a different error:

cURL error 1: Received HTTP/0.9 when not allowed (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://<domain>.test:8080/apps/<app_id>/events?auth_key=<app_key>&auth_timestamp=1743328825&auth_version=1.0&body_md5=<md5body>&auth_signature=<auth_signature> {"exception":"[object] (GuzzleHttp\\Exception\\RequestException(code: 0): cURL error 1: Received HTTP/0.9 when not allowed (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://<domain>.test:8080/apps/<app_id>/events?auth_key=<app_key>&auth_timestamp=1743328825&auth_version=1.0&body_md5=<md5body>&auth_signature=<auth_signature>at /Users/<name>/Developer/<project>/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:276)