question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Laravel Echo is not subscribing to private channel

See original GitHub issue
  • Echo Version: 1.14.1
  • Laravel Version: v9.33.0
  • PHP Version: 8.1.12
  • NPM Version: 8.19.2
  • Node Version: v16.18.0

Description:

Laravel Echo is not subscribing to a private channel. After instantiating and authenticating Laravel Echo the EventListener (‘listen’-Method) never gets called. In the websocket connection is no subscription message and Soketi does not receive any subscription message. Using a public channel works as expected.

Steps To Reproduce:

  1. Setup Laravel Broadcasting with Soketi according to the docs
  2. Generate Event, Listener and a Private Channel
  3. Instantiate Laravel Echo
  4. Listen to an event on that channel
  5. Watch Browser Network Tab

Frontend Code for 3.:

import Echo from 'laravel-echo';

const echo = ref()
const channelName = 'c89e8e0f-d86e-4b5b-887c-3ba24fcc4637'

function setupEcho() {
    const token = useCookie('XSRF-TOKEN').value
    const config = useRuntimeConfig()
    if (!echo.value) {
        echo.value = new Echo({
        authorizer: (channel, options) => {
        return {
            authorize: (socketId, callback) => {
                const response = $fetch(config.baseURL + '/broadcasting/auth', {
                    async onRequest({ request, options }) {
                    options.method = 'post'
                    options.body = {
                        socket_id: socketId,
                        channel_name: channel.name
                    }
                    options.headers = {'X-XSRF-TOKEN': token,
                    'Accept': 'application/json',
                    },
                    options.credentials = 'include'
                    },
                    async onResponseError({ request, response, options }) {
                        console.log(response + response.status)
                    },
                })
                console.log(response)
            }
        };
        },
        broadcaster: 'pusher',
        key: 'app-key',
        cluster: 'mt1',
        wsHost: 'localhost',
        wsPort: 6001,
        forceTLS: false,
        disableStats: true,
        auth: {
            headers: {'X-XSRF-TOKEN': token,
                       'Accept': 'application/json',
            },
        },
        enabledTransports: ['ws', 'wss'],
    });
    }
}

Frontend Code for 4.:

function joinRoomChat() {
    console.log('Joining room: ' + channelName)
    echo.value.private(channelName)
    .listen('.client.stream.started', (e) => {
        console.log('I never get called!')
        console.log(e)
    });
}

Examples for 5.: browser requests: grafik.png

POST-data sent within the request to broadcasting/auth:

{"socket_id":"2329902672.3158557083","channel_name":"private-room.c89e8e0f-d86e-4b5b-887c-3ba24fcc4637"}

The response from the auth-Request:

{"auth":"app-key:ad67d31af255737d954c8e1bf67b7db9e3e44494bd25b7f307d9f270ea7f2b3d"}

This is the request/response-payload of the first (and only) websocket connection Laravel Echo creates: grafik.png

The actual callback function inside the listen-handler never gets called from Laravel Echo. There is just nothing in the browser console. It seems like Laravel Echo does not even send a subscribe message when using private channels.

If using the same event with a public channel Laravel Echo actually subscribes and I get the event data: grafik

I just made a public ‘test’ channel on the backend and changed the event to broadcast on that channel. This is how I changed the Frontend Code:

function joinRoomChat() {
    echo.value.channel('test')
    .listen('.client.stream.started', (e) => {
        console.log('I never get called!')
        console.log(e)
    });
}

I am not sure if there is a bug in Laravel Echo or maybe it is related to Soketi? Nevertheless I had the same problems using the laravel-websocket package, too so I think this bug is Laravel Echo related.

Repository to demonstrate the issue:

The frontend built with NuxtJS:

https://github.com/NK0D1NG/laravel-broadcasting-fe

The backend build with Laravel:

https://github.com/NK0D1NG/laravel-broadcasting-be

Related topics

https://laracasts.com/discuss/channels/laravel/laravel-echo-not-listening-to-events-using-it-with-laravel-homestead-could-it-be-a-compatibility-issue-with-vue-3

I also posted a lot of information about the problem in this post on Laracast (including more Laravel-specific backend code): https://laracasts.com/discuss/channels/laravel/event-listener-never-gets-called-even-if-the-event-gets-fired?page=1&replyId=849115

Issue Analytics

  • State:closed
  • Created 10 months ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
NK0D1NGcommented, Nov 21, 2022

I was finally able to reproduce the issue and solve it. It is important to call the callback on the custom authorizer:

function setupEcho() {
    const token = useCookie('XSRF-TOKEN').value
    const config = useRuntimeConfig()
    channelName.value = 'room.' + roomsStore.currentRoom.roomUuid
    console.log('Channel Name: ' + channelName)
    if (!echo.value) {
        echo.value = new Echo({
        authorizer: (channel, options) => {
        return {
            authorize: (socketId, callback) => {
                const request = $fetch(config.baseURL + '/broadcasting/auth', {
                    async onRequest({ request, options }) {
                    options.method = 'post'
                    options.body = {
                        socket_id: socketId,
                        channel_name: channel.name
                    }
                    options.headers = {'X-XSRF-TOKEN': token,
                    'Accept': 'application/json',
                    },
                    options.credentials = 'include'
                    },
                })
                request.then((response) => {
                    console.log(response)
                    callback(null, response)
                })
            }
        };
        },
        broadcaster: 'pusher',
        key: 'app-key',
        cluster: 'mt1',
        wsHost: 'localhost',
        wsPort: 6001,
        forceTLS: false,
        disableStats: true,
        encrypted: true,
        auth: {
            headers: {'X-XSRF-TOKEN': token,
                       'Accept': 'application/json',
            },
        },
        enabledTransports: ['ws', 'wss'],
    });
    }
}

This part is the important one:

                request.then((response) => {
                    console.log(response)
                    callback(null, response)
                })

I am not sure what callback is used internally by Laravel Echo but it is obligatory for the subscription of private/presence channels to work. All examples in the docs use axios so I had to change some code to work with the fetch API (which is used by the ohmyfetch library). After calling the callback (with a null value as first parameter which seems a bit strange but is also mentioned in the Laravel Docs) the subscription works and I get the event data:

grafik

This issue was not easy to debug, because the same setup works perfectly fine with public channels (including the subscription!) and there are absolutely no errors in the console when trying the same with private channels.

The issue can be closed.

0reactions
NK0D1NGcommented, Nov 20, 2022

@driesvints @jessarcher I provided two demo repositories (links in the original post) which also demonstrate the issue. They should work out of the box after installing the dependencies. Please follow the README of the Laravel Backend Repo to do the setup and create a first user with a custom guard. Even with this simplified setup Laravel Echo does not subscribe to the private channel.

For the frontend just use the newly created user (model is called ‘client’) to login. Then click on the Join Room Chat button which calls the listen-method - but the callback never gets executed and there is no subscription message in the websocket connection.

Read more comments on GitHub >

github_iconTop Results From Across the Web

laravel echo wont subscribe to private channel even the user ...
Okay got this issue resolved, on my nuxt plugin file the authorizer option you just return the response var not respose.data import Echo ......
Read more >
Laravel Echo not working on private channel - Laracasts
I have this following code in my bootstrap.js import Echo from "laravel-echo" window.Echo = new Echo({ broadcaster: 'socket.io', host: 'localhost:6001' }) ...
Read more >
laravel Broadcasting in private channels is not working.( cant ...
I use pusher.com debug console and I realized in PrivateChannel laravel-echo can't subscribe users to Available private channels ...
Read more >
Echo not subscribing to private channel - Laravel.io
I'm trying to subscribe to a users private notification channel using this code var chan = window.Echo.private(`App.Models.User.User.${Laravel.
Read more >
Broadcasting | laravel - GitHub Pages
Events are broadcast over “channels”, which may be specified as public or private. Any visitor to your application may subscribe to a public...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found