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:
- Setup Laravel Broadcasting with Soketi according to the docs
- Generate Event, Listener and a Private Channel
- Instantiate Laravel Echo
- Listen to an event on that channel
- 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:
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:
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:
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
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:
- Created 10 months ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
I was finally able to reproduce the issue and solve it. It is important to call the callback on the custom authorizer:
This part is the important one:
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:
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.
@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.