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.
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');
}
}
php artisan websockets:serve
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,
}
}
})
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.
OMG! Thank you so much!