Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

trip.somers's avatar

Echo Private Channels seem to not be broadcasting.

I have a Redis + socket.io setup in which public channels work perfectly. Private channels, however, do not.

I have verified to the best of my ability that I am successfully subscribing to the private channel with Echo by:

  1. Testing a 'GET' version of the /broadcasting/auth route and getting 'true' output.
  2. Adding 'broadcasting/auth' to my CSRF exceptions list in the CSRF middleware.
  3. Constantly checking my laravel-echo-server output for 'Could not send authentication request.' messages.

As far as I can tell, I am successfully subscribed when I trigger the event to be broadcast.

For my tests, I am broadcasting on a public channel as well as my private channel, and using toastr to display the notifications:

// MyEvent's broadcastOn method
    public function broadcastOn()
    {
        return [
            new Channel('my-public-test'),
            new PrivateChannel('user.77'),
        ];
    }

// javascript
    Echo.private('user.77')

        .listen('MyEvent', (event) => {
            toastr['success']('private channel event received');
        })

    ;

    // PUBLIC CHANNELS
    Echo.channel('my-public-test')

        .listen('MyEvent', (event) => {
            toastr['warning']('public channel event received');
        })

    ;

When I trigger the event, only the public channel notification shows up. I have also removed the public listener in case there's a weird race condition in play.

I'm sure I've left out a detail that someone will ask about, so ask away, and I'll answer as well as I can.

If anyone has any idea why my private channel broadcast isn't being received, I'm all ears.

0 likes
10 replies
trip.somers's avatar

To your first question: according to the documentation, yes.

To your second question, here is a re-pasting of what I wrote above:

I have verified to the best of my ability that I am successfully subscribing to the private channel with Echo by:

  1. Testing a 'GET' version of the /broadcasting/auth route and getting 'true' output.
  2. Adding 'broadcasting/auth' to my CSRF exceptions list in the CSRF middleware.
  3. Constantly checking my laravel-echo-server output for 'Could not send authentication request.' messages.

As far as I can tell, I am successfully subscribed when I trigger the event to be broadcast.

eelkevdbos's avatar

+1 stuck at the same point

  1. public events broadcasting fine
  2. successful authentication logged in laravel-echo-server console
  3. successful subscription spotted in socket.io data frames to correct channel
1 like
trip.somers's avatar

This is interesting. I didn't know about the web sockets panel in Chrome Dev Tools, but having looked at it just now, I'm apparently not successfully subscribing to the private channel.

It looks like it's not even trying to authenticate... ? I have only one websocket entry on the left pane, and only one 'subscribe' request (for the public channel) in that websocket's frames.

Thoughts?

UPDATE / EXTRA NOTE: The weird part is if I change the private channel name to something that's invalid for my user (e.g. "user.2" when my user ID is 1), then I get errors that the authentication failed in my laravel-echo-server console but the data frames show no subscription attempt.

UPDATE #2: I clearly don't understand the data frames information. With an invalid private channel listener, I see no subscribe attempt to my public channel, but I still receive the public events.

UPDATE #3: After tweaking laravel-echo-server's private-channel.js file, I am able to see output when I successfully connect to my private channels. I altered it to show me the channel name on success, and I am seeing the correct channel name. I am almost definitely subscribed correctly.

eelkevdbos's avatar
Level 1

I got it to work (my queue wasn't flushing properly). Disclaimer for the following, I'm using a docker setup so some things might be 'exotic'.

If it is of any help, this is my configuration file for the laravel-echo-server:

{
"appKey": {{SECRET}},
"authHost": "http://web:8000",
"authEndpoint": "/broadcasting/auth",
"database": "redis",
"databaseConfig": {
    "redis": {
        "port": "6379",
        "host": "redis"
    }
},
"devMode": true,
"host": "0.0.0.0",
"port": "6001",
"referrers": [],
"socketio": {},
"sslCertPath": "",
"sslKeyPath": ""
}

This is my Echo client-side initialization:

import Echo from "laravel-echo"

window.Echo = new Echo({
    namespace: 'MyApp.Events',// !warning . -> \\ conversion
    broadcaster: 'socket.io',
    host: Laravel.baseUrl + ':6001' //personal addition for docker

});

What type of authentication middle ware is your app primarily using?

trip.somers's avatar

That's a question with a fun answer... I have a LegacyAuth service that I updated to map into Laravel's native Auth using a custom guard. I already verified that all of my web routes and everything are behaving correctly.

In my BroadcastServiceProvider, I'm declaring the middleware like this:

Broadcast::routes(['middleware' => ['web','legacy.auth']]);

Also, please read my updates in previous comment. I've added some information, and I believe that I have verified that I am successfully subscribed.

Regarding your queue not flushing... How does that work? I'm using the default queue for all of my broadcasts, so if the public ones get processed, shouldn't the private ones?

UPDATE #1: Laravel Echo Server has a debug mode... That... would have been useful for me to realize like 2 days ago.

trip.somers's avatar

You were onto something. On a whim, I decided to trigger my events while php artisan queue:listen was running, and they came through. This makes no sense to me.

Why would my supervisor-monitored workers process public events but not private events? Why does queue:listen process them?

I'm so confused now.

trip.somers's avatar

Aaaaand... that's apparently the answer. My queue workers had been running longer than I thought they had with old .env and config. Once I ran php artisan queue:restart everything started working.

I feel stupid and relieved at the same time.

Although, this doesn't explain why the public channels were still working. :-/

LytraX's avatar

@trip.somers The reason why public channels were working, is because the PHP code that the Queue was running had only the public channels configured; then you went and added a private channel to your code but the Queue didn't have had these code updates and got everything updated (including the new private channel) when you did restart it.

Same goes for the Laravel Horizon nowadays. If you're using Laravel Horizon then you need to restart it after we make changes to our code php artisan horizon:terminate.

Please or to participate in this conversation.