Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save 1mursaleen/2f2265976d59267f3bfccb339b27be44 to your computer and use it in GitHub Desktop.
Save 1mursaleen/2f2265976d59267f3bfccb339b27be44 to your computer and use it in GitHub Desktop.
Common Problems faced while setting up private channels with laravel-echo & laravel-echo-server.
I'll start with the basics and proceed to addressing the common problems
faced while setting up private channels with laravel-echo & laravel-echo-server.
If you are getting these errors while setup; 401, 403, 419 etc, as I did in my experience.
this gist will help you fix these errors.
Although this gist addresses common problems of laravel-echo-server setup, some problems are similar with Pusher setup.
So it might also be useful if you're having problems with setting up Pusher with Echo.
I'll try to cover eveything and try to use appropriate highlighting to single out each common problem.
I use '---' to separate each section or common problem.
---
NPM Install:
npm install dotenv --save
npm install laravel-echo --save
npm install laravel-echo-server --save
npm install laravel-echo-server --save -g
note that I've installed 'laravel-echo-server' globally and locally in the project.
Global installation will allow us to use cli commands for this package, like 'laravel-echo-server init'
Local installation because of this good practice: https://medium.com/@titasgailius/running-laravel-echo-server-the-right-way-32f52bb5b1c8
---
first and foremost, make sure you have csrf meta tag in the html <head>. Otherwise you'll get 419 error while listening to channels
<meta content="{{ csrf_token() }}" name="csrf-token">
---
In config/app.php
Comment out the line below
App\Providers\BroadcastServiceProvider::class,
---
In .env, you must set these variables:
APP_URL=http://your_domain.com
// common mistake: be carefull while setting the scheme 'http' or 'https' in both local and production environments.
// this mistake can cause 403, 404 error or an error without a status
APP_NAME=YourAppName
// I'd suggest you use a clean name without underscores, hyphens, periods or any symbols.
// errors: 401 403
JWT_SECRET=random_string
JWT_TTL=1440
// set these only if you are using this package for jwt authentication https://github.com/tymondesigns/jwt-auth
CACHE_DRIVER=redis // optional but I'd suggest redis
SESSION_DRIVER=redis // optional but I'd suggest redis
QUEUE_CONNECTION=redis // this refers to the config/queue.php file
BROADCAST_DRIVER=redis
Important Note:
your Redis installation has 0 to 16 DBs
If you plan to use redis as CACHE_DRIVER, SESSION_DRIVER and BROADCAST_DRIVER -- which I'd certainly suggest -- you must use different DB for each driver.
It is widely reported by many laravel developers that redis pub/sub for BROADCAST_DRIVER is affected if a single redis db is used.
To use different DBs make the below entries in .env, each of these we'll set in config/database.php as redis connections.
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_BROADCAST_DB=2
// error: events are published to channels but echo-server won't listen
---
In config/database.php, at the bottom there is 'Redis Databases' section in which redis's 'default' & 'cache' connections are defined like this
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
// add 'broadcast' db connection after 'cache' like this:
'broadcast' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_BROADCAST_DB', 2),
],
---
In app\Providers\BroadcastServiceProvider.php, make sure the boot function has Broadcast::routes() and requires 'routes/channels.php'
public function boot()
{
Broadcast::routes(); // by default these routes use middleware 'auth:web'
// Broadcast::routes(['middleware' => ['auth:api']]); // for auth:api
// Broadcast::routes(['middleware' => ['jwt.auth']]); // for jwt package https://github.com/tymondesigns/jwt-auth
require base_path('routes/channels.php');
}
---
In config/database.php, at the bottom under redis db settings if you have: redis -> options -> prefix
Then all your channels that you brodcast on will have a prefix 'YourAppName_database_' or 'laravel_database_'
for example: YourAppName_database_mymessageschannel
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
// You can customize the prefix however you want, but keep in mind that while listening to the channles you'll have to use this prefix
// error: events are published to channels but echo-server won't listen
],
...
]
---
use 'php artisan make:event EventName' to make an event that should be broadcast. The new Event will be placed in 'app\Events' directory.
I used 'php artisan make:event MessageSent'
then in app\Events\MessageSent
<?php
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public function __construct(Message $message)
{
//
$this->message = $message;
//
$this->dontBroadCastToCurrentUser(); // if you don't want to broadcast to the user who generated the event.
}
public function broadcastOn()
{
return new PrivateChannel("room." . $this->message->room_id);
// Very very Important Note: because it sucked a lot of my time
// If you have a redis prefix setup in config/database.php, which I have discussed in the previous section,
// you'll have to use the prefix while listening to the channel in Laravel Echo.
// for example: if you have prefix 'YourAppName_database_', the resulting channel will be 'YourAppName_database_room.{room_id}'
// error: 401, 403
}
}
---
In routes/channels.php
Broadcast::channel('room.{id}', function ($user, $id) {
return (int) $user->room_id === (int) $id;
},
['guards' => ['api']]); // you can optionally give guards as the third agument, if you are using a guard other than the 'web' guard.
// the user must be logged in to authenticate private channels, laravel will automatically place $user as the current logged in user.
// Important Note: Again, if there's a redis prefix setup, as I have discussed in the section above you must prefix it here
// Broadcast::channel('YourAppName_database_room.{id}', function ($user, $id) {
// 'YourAppName_database_' is the redis prefix.
// error: 401, 403
---
Do 'npm install --save socket.io-client'
In resources\...\bootstrap.js, configure import and configure Laravel Echo for laravel-echo-server
import Echo from 'laravel-echo'
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
---
// make echo.js in the project directory (where .env is) and copy paste below code and save
// here we use the locally installed 'laravel-echo-server' package
// dotenv will help you get variables from .env file so you'll have a single environment file for both laravel and laravel-echo-server
// after you save the code, you can open a terminal in the project directory and run 'node echo' to start laravel-echo-server
require('dotenv').config();
const env = process.env;
require('laravel-echo-server').run({
authHost: env.APP_URL,
devMode: env.APP_DEBUG,
database: "redis",
databaseConfig: {
redis: {
host: env.REDIS_HOST,
port: env.REDIS_PORT,
family: 4,
db: env.REDIS_BROADCAST_DB // 'REDIS_BROADCAST_DB' is the separate db we have setup in the previous section for broadcast channels
}
}
// more laravel-echo-server options can be added, see it's documentation
});
---
In your vue component, where you'd like to listen to your channel
forexample: resources\js\components\ExampleComponent.vue
mounted () {
var that = this
// if you are using jwt auth, you must set the following headers of window.Echo options to get authenticated for private channels and you must have a mechanism to get the jwt token
// window.Echo.connector.options.auth.headers['Authorization']
// window.Echo.options.auth
// if you are not using jwt, skip the two lines below
window.Echo.connector.options.auth.headers['Authorization'] = 'Bearer ' + jwt_token
window.Echo.options.auth = {
headers: {
Authorization: 'Bearer ' + jwt_token,
},
},
window.Echo.private(`room.${that.room.id}`) // *
.listen('MessageSent', function (e)
{
// doStuff
})
// *
// Important Note: Again, if there's a redis prefix setup, as I have discussed in the previous sections you must prefix it here
// window.Echo.private(`YourAppName_database_room.${that.room.id}`)
// the channel name becomes YourAppName_database_room.{room_id}
// 'YourAppName_database_' is the redis prefix.
// error: 401, 403
}
@interludic
Copy link

Sweet mother of god

@flowser

This comment was marked as abuse.

@litvinenkow
Copy link

where is auth routes configured?

@yatutmaster
Copy link

yatutmaster commented Oct 21, 2020

Thanks, kind man!

@M-Abdullahi
Copy link

Setting up websockets with vue and laravel echo is a pain in the ass. Used 8hrs+ and still not getting it to run

@swanback
Copy link

swanback commented Jan 7, 2021

This is a fantastic help. Had I found the key that as of Jan 2021 at least, you must use socket.io-client version 2.3.0, not version 3.0, it would have saved me many (more) hours of head-banging.

@Mozakar
Copy link

Mozakar commented Apr 13, 2021

you must use socket.io-client version 2.3.0, not version 3.0, it would have saved me many (more) hours of head-banging.

Thanks, I wasted two weeks because of the version

@rahul1961
Copy link

Setting up websockets with vue and laravel echo is a pain in the ass. Used 8hrs+ and still not getting it to run

Just if you are wondering, there is this prefix on laravel-echo for client side, called, private, so if you have a laravel private channel xyz, for laravel echo to work, you need to rename it to private-xyz then only It will work.

@Geovanek
Copy link

Geovanek commented Oct 14, 2021

I have this error and I don't know what can solve it.

laravel-echo-server_1  | [12:20:31 AM] - Sending auth request to: localhost/broadcasting/auth
laravel-echo-server_1  |
laravel-echo-server_1  | [12:20:31 AM] - Error authenticating wcoGigP-jG_jjDARAAAL for private-athletes.1
laravel-echo-server_1  | Error: Invalid URI "localhost/broadcasting/auth"
laravel-echo-server_1  |     at Request.init (/usr/src/app/node_modules/request/request.js:273:31)
laravel-echo-server_1  |     at new Request (/usr/src/app/node_modules/request/request.js:127:8)
laravel-echo-server_1  |     at request (/usr/src/app/node_modules/request/index.js:53:10)
laravel-echo-server_1  |     at Function.post (/usr/src/app/node_modules/request/index.js:61:12)
laravel-echo-server_1  |     at /usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:57:27
laravel-echo-server_1  |     at new Promise (<anonymous>)
laravel-echo-server_1  |     at PrivateChannel.serverRequest (/usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:54:16)
laravel-echo-server_1  |     at PrivateChannel.authenticate (/usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:21:21)
laravel-echo-server_1  |     at Channel.joinPrivate (/usr/src/app/node_modules/laravel-echo-server/dist/channels/channel.js:68:22)
laravel-echo-server_1  |     at Channel.join (/usr/src/app/node_modules/laravel-echo-server/dist/channels/channel.js:21:22)
laravel-echo-server_1  | Error sending authentication request.````

@1mursaleen
Copy link
Author

I have this error and I don't know what can solve it.

laravel-echo-server_1  | [12:20:31 AM] - Sending auth request to: localhost/broadcasting/auth
laravel-echo-server_1  |
laravel-echo-server_1  | [12:20:31 AM] - Error authenticating wcoGigP-jG_jjDARAAAL for private-athletes.1
laravel-echo-server_1  | Error: Invalid URI "localhost/broadcasting/auth"
laravel-echo-server_1  |     at Request.init (/usr/src/app/node_modules/request/request.js:273:31)
laravel-echo-server_1  |     at new Request (/usr/src/app/node_modules/request/request.js:127:8)
laravel-echo-server_1  |     at request (/usr/src/app/node_modules/request/index.js:53:10)
laravel-echo-server_1  |     at Function.post (/usr/src/app/node_modules/request/index.js:61:12)
laravel-echo-server_1  |     at /usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:57:27
laravel-echo-server_1  |     at new Promise (<anonymous>)
laravel-echo-server_1  |     at PrivateChannel.serverRequest (/usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:54:16)
laravel-echo-server_1  |     at PrivateChannel.authenticate (/usr/src/app/node_modules/laravel-echo-server/dist/channels/private-channel.js:21:21)
laravel-echo-server_1  |     at Channel.joinPrivate (/usr/src/app/node_modules/laravel-echo-server/dist/channels/channel.js:68:22)
laravel-echo-server_1  |     at Channel.join (/usr/src/app/node_modules/laravel-echo-server/dist/channels/channel.js:21:22)
laravel-echo-server_1  | Error sending authentication request.````

Everyone! I suggest every developer should use LARAGON and ditch xampp wampp etc.
You'll save a lot of time on setting up & resolving environment issues, like this localhost issue.
You'll get http://{project}.test urls automatically.

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