Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save sdwru/2fc0cd414b12cabfb3b84d05bb693375 to your computer and use it in GitHub Desktop.
Save sdwru/2fc0cd414b12cabfb3b84d05bb693375 to your computer and use it in GitHub Desktop.
Laravel-websockets on Laravel API backend + Laravel Echo on Vue.js front end on different server/domain using private channel.md

These are my notes on how I got all the basics working end to end.

Laravel API backend and Vue.js frontend are 2 different servers on different public IP addresses and different domains. I am using pure Vue.js on the front end. Most instructions assume Laravel Vue.js is being used which is structured slightly different with different file names and directories.

  • Laravel API backend domain name (api.somedomain.com)
  • Vue.js frontend domain name (client.somedomain.com)

No database is needed for any of this to work using sync queue. That is only needed in production if/when you use a database queue.


Laravel API backend server (api.somedomain.com)

composer require beyondcode/laravel-websockets
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"

Make sure App\Providers\BroadcastServiceProvider::class is uncommented

config/app.php

'providers' => [
  ...
  App\Providers\BroadcastServiceProvider::class,
],

.env

BROADCAST_DRIVER=pusher
QUEUE_CONNECTION=sync
PUSHER_APP_ID=testapp
PUSHER_APP_KEY=websocketkey
PUSHER_APP_SECRET=somethingsecret
PUSHER_APP_CLUSTER=mt1

config/broadcasting.php

'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'),
            //'useTLS' => false,
            'encrypted' => true,
            'host' => '127.0.0.1',
            'port' => 6001,
            'scheme' => 'http',
        ],
    ],
    ...

config/websockets.php

'apps' => [
      [
          'id' => env('PUSHER_APP_ID'),
          'name' => env('APP_NAME'),
          'key' => env('PUSHER_APP_KEY'),
          'secret' => env('PUSHER_APP_SECRET'),
          'path' => env('PUSHER_APP_PATH'),
          'capacity' => null,
          'enable_client_messages' => true,
          'enable_statistics' => true,
      ],
  ],

routes/api.php

Route::get('test', function () {
    event(new App\Events\Test());
    return "Event has been sent!";
});

routes/channels.php

// This is only for testing purposes
Broadcast::channel('testchannel', function ($user) {
    return true;
}); 

// This is probably closer to what most would use in production
Broadcast::channel('user.{id}', function ($user, $id) {
    //return true if api user is authenticated
    return (int) $user->id === (int) $id;
});

app/Http/Middelware/VerifyCsrfToken.php

protected $except = [
    'broadcasting/auth',
];

app/Events/Test.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class Test implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct()
    {
      //
    }

    public function broadcastOn()
    {
        return new PrivateChannel('testchannel');
    }
}

Run websockets server on Laravel api backend

php artisan websockets:serve


Vue.js frontend (client.somedomain.com)

npm install --save laravel-echo pusher-js

.env Note: The variable MUST be prefixed with VUE_APP_ https://cli.vuejs.org/guide/mode-and-env.html#modes

VUE_APP_PUSHER_APP_KEY='websocketkey'

Add Echo globally. In laravel vue that file is usually called bootstrap.js. In pure Vue.js it is called main.js

main.js

import Echo from 'laravel-echo'
window.Pusher = require('pusher-js')

// This assumes you have already saved your bearer token in your browsers local storage
const token = localStorage.getItem('user-token')

window.Echo = new Echo({
  broadcaster: 'pusher',
  key: process.env.VUE_APP_MIX_PUSHER_APP_KEY,
  wsHost: 'api.somedomain.com',
  authEndpoint: 'http://api.somedomain.com/broadcasting/auth',
  encrypted: true,
  forceTLS: false,
  wsPort: 6001,
  wssPort: 6001,
  disableStats: true,
  enabledTransports: ['ws', 'wss'],
  auth: {
    headers: {
      authorization: 'Bearer ' + token,
    }
  }
})

Add the Echo channel to whichever *.vue file we want to test this on

src/App.vue

...
created() {
  window.Echo.private('testchannel')
      .listen('Test', (e) => {
          console.log('test successful ' + e)
  })

All done. Now open your src/App.vue Single Page App in a chrome/firefox browser with the developer/inspect console window opened.

In a separate browser tab/window browse to http://api.somedomain.com/test to fire the test event. You should see "test successful" showing up in your SPA page developer console.

The end.

@qiongjiayatou
Copy link

OMG! Thank you so much!

@juanxodj
Copy link

juanxodj commented Aug 5, 2022

I have followed all the steps but it still gives me a 403 (Forbidden) error.

@asim-altayb
Copy link

amazing summarize article ! love it @sdwru

@thond1st
Copy link

thond1st commented Mar 8, 2023

I have followed all the steps but it still gives me a 403 (Forbidden) error.

Same as mine but I guess it has something to do with Https
Hope to know if you were successful in solving the 403 error

@birukindrias
Copy link

love it @sdwru!

@joy2323
Copy link

joy2323 commented Apr 26, 2023

Thank you @sdwru this helped me a lot.

@UpdateWebTeam
Copy link

Thanks .. this is amazing . but how can i use this 'laravel-echo' in a web worker. can someone please guide me ?

@bernardobiondini
Copy link

I keep receiving this error when trying to acces route test

"Pusher error: cURL error 7: Failed to connect to 127.0.0.1 port 6001: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

Any ideas why it may be occuring? My configs are exacly like the article's

@sdwru
Copy link
Author

sdwru commented Jan 23, 2024

I keep receiving this error when trying to acces route test

"Pusher error: cURL error 7: Failed to connect to 127.0.0.1 port 6001: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

Any ideas why it may be occuring? My configs are exacly like the article's

As stated in the procedure:

Laravel API backend and Vue.js frontend are 2 different servers on different public IP addresses and different domains.

It looks like you are trying to connect to localhost which is not exactly like the procedure.

I probably should have clarified further that neither of those servers are localhost. In other words, neither of them are the same computer that you are trying to browse from. I wrote this procedure quite awhile ago so it could be that there is something else going on because of newer versions of the software used.

@bernardobiondini
Copy link

It looks like you are trying to connect to localhost which is not exactly like the procedure.

I probably should have clarified further that neither of those servers are localhost. In other words, neither of them are the same computer that you are trying to browse from. I wrote this procedure quite awhile ago so it could be that there is something else going on because of newer versions of the software used.

Thank you for the answer. I'm still getting the same error after trying several solutions btw. Lmk if you have any ideas pls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment