Every time I switch to the private channel nothing is ever received on the browser but when using just a standard channel it works. My current setup includes a Vue CLI app for the front-end and a Laravel API as the backend using Laravel Passport for authentication.
This is the code which is being used to connect to Pusher.
import LaravelEcho from 'laravel-echo';
// ...
export const Echo = new LaravelEcho({
broadcaster: 'pusher',
key: pusherKey,
cluster,
encrypted: true,
});
Echo.connector.pusher.config.authEndpoint = `${baseURL}/broadcasting/auth`;
store.watch((state: any) => state.$auth.token, (token: string) => {
Echo.connector.pusher.config.auth.headers['Authorization'] = `Bearer ${token}`;
});
store.watch((state: any) => state.$auth.user, (n: any, o: any) => {
if (n) {
console.log(`App.User.${n.id}`); // This is being logged to the console App.User.1
Echo.private(`App.User.${n.id}`)
.listen('.friend.request', (e: any) => {
console.log({ e });
});
}
});
And this is the channel route file:
<?php
Broadcast::channel('App.User.{id}', function ($user, $id) {
return true;
// return (int) $user->id === (int) $id;
});
A cut down version of the event.
<?php
namespace App\Events;
// ...
class FriendRequestSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
// ...
public function broadcastOn()
{
return new PrivateChannel("App.User.{$this->friend->id}");
}
// ...
}
And I have set up this testing route:
<?php
Route::get('/', function (Request $request) {
event(new FriendRequestSent(User::find(1), User::find(1)));
});
After running the Echo.private()...
code I can see the following show up in my Pusher dashboard:
And then after firing off the event from the /
route:
Finally, Pusher picking up the event and nothing showing in the console:
However, if I change new PrivateChannel(...)
to new Channel(...)
and then use Echo.channel
instead of Echo.private
it will start to display something in the console.
Does anyone know why this could be happening?
An update to this, I found this webpage: Pusher Docs - Debugging
Pusher : : ["Event sent",{"event":"pusher:subscribe","data":{"auth":"some_auth_code_returned_from_api_broadcasting_auth","channel":"private-App.User.1"}}]
Pusher : : ["Event recd",{"event":"pusher_internal:subscription_succeeded","channel":"private-App.User.1","data":{}}]
Pusher : : ["No callbacks on private-App.User.1 for pusher:subscription_succeeded"]
I can see by the final output No callbacks on private-App.User.1...
could be causing the issue but the only things I could find on it were:
BROADCAST_DRIVER=pusher
channels.php
:<?php
// Notice {userId} rather than {id}.
Broadcast::channel('App.User.{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
I have now tried this with Socket.IO and I'm getting the same results:
Socket.IO console output:
[6:36:11 AM] - Preparing authentication request to: http://isapi.test
[6:36:11 AM] - Sending auth request to: http://isapi.test/api/broadcasting/auth
[6:36:12 AM] - gT9--_C_2c-KwoxLAAAE authenticated for: private-App.User.1
[6:36:12 AM] - gT9--_C_2c-KwoxLAAAE joined channel: private-App.User.1
My Socket.IO configuration:
import io from 'socket.io-client';
(window as any).io = io;
export const Echo = new LaravelEcho({
broadcaster: 'socket.io',
host: `${baseURL.substr(0, baseURL.length - 4)}:6001`,
encrypted: true,
});
Echo.connector.socket.io.opts.authEndpoint = `${baseURL}/broadcasting/auth`;
store.watch(
(state: any) => state.$auth.token,
(token: string) => {
Echo.connector.socket.io.opts.auth.headers.Authorization = `Bearer ${token}`;
},
);
So I have created a completely fresh install of Vue and Laravel with the following dependencies:
Laravel:
Vue:
And it works so I'm just going to have to find out what I did differently and see if I can solve it that way. If you would like to see this testing code I have placed it in this repository.
As always it was a really simple solution which was overlooked.
I had two store.watch
's; one on the token and one on the user. The user one must have run first and then the token one ran afterwards causing the token to not be set when connecting to the private channel. E.g.
store.watch(
(state: any) => state.$auth.token,
(token: string) => {
Echo.connector.pusher.config.auth.headers.Authorization = `Bearer ${token}`;
},
);
store.watch(
(state: any) => state.$auth.user,
(n: any, o: any) => {
if (n) {
// Added this line to fix the issue.
Echo.connector.pusher.config.auth.headers.Authorization = `Bearer ${store.state.$auth.token}`;
Echo.private(`App.User.${n.id}`).listen(
'.friend.request',
(data: any) => {
// store.state.$friends.requests = data;
console.log({ data });
},
);
} else if (o) {
Echo.private(`App.User.${o.id}`)
.stopListening('.friend.request');
}
},
);