-
-
Save 1mursaleen/2f2265976d59267f3bfccb339b27be44 to your computer and use it in GitHub Desktop.
| 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 | |
| } | |
Setting up websockets with vue and laravel echo is a pain in the ass. Used 8hrs+ and still not getting it to run
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.
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
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.
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.````
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.
Thanks, kind man!