Building a real-time chat demo app with Laravel WebSockets (Part 3) cover image

Building a real-time chat demo app with Laravel WebSockets (Part 3)

Tom Oehlrich

In part 1 we set up the websocket server application and provided an API endpoint for our client chat app.

In part 2 we set up the client chat app using Laravel and Vue.js and used Laravel Echo as a wrapper for the Javascript implementation.


There was quite some trial and error involved in getting everything set up.
A lot of it evolved around the websocket server statistics not being updated in the database, thus no statistics graph showing up in the dashboard.
Looking at the GitHub repository of Laravel WebSockets this seems to be a problem among users.

WebSocket Server (local machine)

This is was worked for me on my local machine (WAMP). The exact combination of settings might not even be necessary but I stopped at the point when it was working for me.

In config/websockets.php we obviously have to enable statistics. Statistics should be enabled by default anyway though.

'apps' => [
    [
        ...
        'enable_statistics' => true
        ...
    ]
]

perform_dns_lookup should be true.

'perform_dns_lookup' => true,

In config/broadcasting.php the host in the pusher connection is set to 127.0.0.1

'pusher' => [
    ...
    'options' => [
        ...
        'host' => '127.0.0.1',
        ...
    ],
],

APP_URL in .env needs to be set to the actual URL where your websocket server dashboard is:

APP_URL=http://[YOUR WEBSOCKET SERVER DOMAIN]

This environment variable seems to be used when addressing the route that stores statistics data in the database.

Also clear your config cache via artisan and restart the websocket server.
And don't forget to wait for the first graphs to appear.


Demo Chat app (local machine)

In resources/js/bootstrap the Echo configuration looks like this

window.Echo = new Echo({
    ...
    encrypted: false,
    wsHost: '[YOUR WEBSOCKET SERVER DOMAIN]',
    wsPort: 6001,
    disableStats: true,
    enabledTransports: ['ws']
    ...
});

The axios POST in resources/js/components/Chat.vue calls the endpoint

http://[YOUR WEBSOCKET SERVER DOMAIN]/api/message

WebSocket Server (Digital Ocean, SSL)

This is was worked for me on my Digital Ocean droplet after setting up Let's Encrypt. Again, you might not need all these configuration settings. I haven't tried all combinations but have rather stopped at the point when it was working for me.

In config/websockets.php:

'apps' => [
    [
        ...
        'enable_statistics' => true
        ...
    ]
],

'statistics' => [
    ...
    'perform_dns_lookup' => true,
    ...
],

For the SSL configuration I simply use the full paths to the Let's Encrypt cert and private key.

'ssl' => [
    'local_cert' => '/etc/letsencrypt/live/[YOUR WEBSOCKET SERVER DOMAIN]/cert.pem',

    'local_pk' => '/etc/letsencrypt/live/[YOUR WEBSOCKET SERVER DOMAIN]/privkey.pem',

    'passphrase' => null,

    'verify_peer' => false,
],

config/broadcasting.php looks like this:

'pusher' => [
    ...
    'options' => [
        'host' => '[YOUR WEBSOCKET SERVER DOMAIN]',
        'port' => 6001,
        'scheme' => 'https',
        'curl_options' => [
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
        ]
    ],
],

APP_URL in .env is set to the domain of the websocket server.

APP_URL=https://[YOUR WEBSOCKET SERVER DOMAIN]

Demo Chat app (Digital Ocean, SSL)

Laravel Echo is configured like this in resources/js/bootstrap:

window.Echo = new Echo({
    ...
    encrypted: true,
    wsHost: '[YOUR WEBSOCKET SERVER DOMAIN]',
    wssHost: '[YOUR WEBSOCKET SERVER DOMAIN]',
    wsPort: 6001,
    wssPort: 6001,
    disableStats: true,
    enabledTransports: ['ws', 'wss']    
    ...
});

The axios POST in resources/js/components/Chat.vue calls the endpoint

https://[YOUR WEBSOCKET SERVER DOMAIN]/api/message

You can find the full source code in this GitHub repo and this GitHub repo.