Laravel-websockets: Connecting to pusher.com?

Created on 20 Jan 2019  路  13Comments  路  Source: beyondcode/laravel-websockets

Hello everybody,

I just tried to get laravel-websockets running, but unfortunately I am getting this event:

[Error] Preflight response is not successful
[Error] XMLHttpRequest cannot load https://sockjs.pusher.com/pusher/app/my-secret/991/vddue3fm/xhr_streaming?protocol=7&client=js&version=4.3.1&t=1548017651876&n=1 due to access control checks.
[Error] Failed to load resource: Preflight response is not successful (xhr_streaming, line 0)
[Error] Failed to load resource: the server responded with a status of 404 () (index.js.map, line 0)
[Error] WebSocket connection to 'wss://laravel.dev/app/my-secret?protocol=7&client=js&version=4.3.1&flash=false' failed: Unexpected response code: 404
[Error] Preflight response is not successful
[Error] XMLHttpRequest cannot load https://sockjs.pusher.com/pusher/app/my-secret/664/8svmmp0t/xhr?protocol=7&client=js&version=4.3.1&t=1548017655882&n=2 due to access control checks.
[Error] Failed to load resource: Preflight response is not successful (xhr, line 0)

I am running on Laravel homestead with the following environment:

  • Laravel 5.7

config/websockets.php

<?php

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

return [

    /*
     * 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 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' => true,
        ],
    ],

    /*
     * 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,

        /*
         * 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' => [
        /*
         * Path to local certificate file on filesystem. It must be a PEM encoded file which
         * contains your certificate and private key. It can optionally contain the
         * certificate chain of issuers. The private key also may be contained
         * in a separate file specified by local_pk.
         */
        'local_cert' => null,

        /*
         * Path to local private key file on filesystem in case of separate files for
         * certificate (local_cert) and private key.
         */
        'local_pk' => null,

        /*
         * Passphrase for your local_cert file.
         */
        'passphrase' => null,
    ],

    /*
     * 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,
];

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: "pusher", "redis", "log", "null"
    |
    */

    'default' => env('BROADCAST_DRIVER', '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' => [

        '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' => 'http'
            ],
        ],

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
        ],

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

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

    ],

];

app.js

window.Echo = new Echo ({
    broadcaster: 'pusher',
    key: 'my-key',
    wsHost: window.location.hostname,
    wsPort: 6001,
    disableStats: true,
});

window.location.hostname resolves to laravel.dev.

What am I doing wrong?

Most helpful comment

Hi! Try adding enabledTransports like:

window.Echo = new Echo ({
    broadcaster: 'pusher',
    key: 'my-key',
    wsHost: window.location.hostname,
    wsPort: 6001,
    disableStats: true,
        enabledTransports: ['ws', 'wss'], // <-- only use ws and wss as valid transports
});

and, of course, be sure that your server is running ok

All 13 comments

Hi @SPQRInc.

In your .ENV, make sure to add correct Pusher credentials in the PUSHER_APP_ID, PUSHER_APP_KEY. and PUSHER_APP_SECRET. You will also need to set the BROADCAST_DRIVER to "pusher", as explained in the documentation. This is because Laravel Websockets uses the Pusher API built into Laravel.

You will also need to replace 'my-key' with your Pusher key.

After you have updated your .ENV, make sure to run yarn run dev to add the Pusher credentials into the app.js compiled file.

Next, run php artisan websockets:serve and it should be working correctly. If it doesn't work correctly, I've found that changing the wsHost to 127.0.0.1 has worked for me.

I'm not sure why it still needs to communicate with Pusher, maybe this is incorrect - but this is how I've got it working on multiple occasions, after running into your 404 issues! Just tonight myself and another developer were left mind-boggled to why it still needs to verify Pusher credentials if it's using a custom server. That's also why you've seen the Pusher XHR requests :)

Hi! Try adding enabledTransports like:

window.Echo = new Echo ({
    broadcaster: 'pusher',
    key: 'my-key',
    wsHost: window.location.hostname,
    wsPort: 6001,
    disableStats: true,
        enabledTransports: ['ws', 'wss'], // <-- only use ws and wss as valid transports
});

and, of course, be sure that your server is running ok

Hi @Sammyjo20,

maybe I misunderstood the post on https://laracasts.com/discuss/channels/laravel/install-and-laravel-echo-server-multiple-times-on-the-same-server . There was a question, whether a pusher.com-account is still needed and I understood that it's not needed as laravel-websockets replaces pusher.com. Is that incorrect?

See, you're right because the documentation doesn't specify that you need a valid Pusher.com account, but strangely - I've not actually been able to get it working without using valid pusher credentials. Because you specify the custom host and port (wsHost) it will use your server for the websockets but on pageload, Pusher will still verify the credentials. (Edit: which, makes no sense to me 馃槀)

In your developer tools, under Network - if you go to "WS" (Websocket) do you see your server connecting?

Hm, so it is a bug?

I see the following message:

WebSocket connection to 'wss://laravel.dev/app/my-secret?protocol=7&client=js&version=4.3.1&flash=false' failed: Unexpected response code: 404
https://laravel.dev/js/index.js.map

But in my network-tab, I see websocket-connections:

bildschirmfoto 2019-01-21 um 09 03 34

Yes, I believe it's a bug. See in the URL - wss://laravel.dev/app/my-secret Have you tried adding a valid secret from Pusher?

Hi @Sammyjo20

I added my valid secret key (my-valid-secret-key here). Now I am getting this response:

WebSocket connection to 'wss://laravel.dev/app/my-valid-secret-key?protocol=7&client=js&version=4.3.1&flash=false' failed: WebSocket is closed before the connection is established.

But this is only a problem when I am using SSL with my Homestead VM.

Without using SSL, I am getting no errors.

Have you got a valid certificate for your domain laravel.dev? You can install SSL on homestead with this tutorial: https://medium.com/@adnanxteam/how-to-setup-https-with-laravel-homestead-ad7915470fa8

This is because the wss:// protocol is web sockets secure

Solves it, thanks a lot!

I'm facing this problem and the solution discussed above doesn't seem to be working. I'm using the credentials from pusher.com [app id, key, secret and cluster ].

When I comment out enabledTransports: ['ws', 'wss'] , my app makes a connection to ttps://sockjs-ap2.pusher.com/pusher/app/.... as an XHR request. But if I enable that option, I get error in the console that says -

WebSocket connection to 'wss://ce.dev:6001/app/f1c4057cb5be60d8863f?protocol=7&client=js&version=4.4.0&flash=false' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

I'm using Laravel Valet and the domain ce.dev is correctly served using SSL. I'm trying to figure out which step am I missing out on. Would really appreciate help in identifying the fix.

@netzhelden
hello How are you please i'm getting this error any idea how to solve it
aaaa

@netzhelden
i'm usong laravel websocket
reverse proxy nginx
...

See, you're right because the documentation doesn't specify that you need a valid Pusher.com account, but strangely - I've not actually been able to get it working without using valid pusher credentials. Because you specify the custom host and port (wsHost) it will use your server for the websockets but on pageload, Pusher will still verify the credentials. (Edit: which, makes no sense to me )

In your developer tools, under Network - if you go to "WS" (Websocket) do you see your server connecting?

You do not need a pusher.com account just set all the pusher env variables to something like 'local' and it will work just fine :)

Was this page helpful?
0 / 5 - 0 ratings