Echo processing twice after Intertia Logout/Login
Hi,
Just trying Laravel Echo/Pusher for the first time in my Vue application and I'm getting some strange behaviour with each event triggering twice.
But it only happens when I logout and log back in again and only if I logout via an Inertia method (via Link or form helper):
Logging out with this causes double-counting next time I login:
<Link href="/logout" method="get" as="button" type="button">Inertia Logout</Link>
This doesn't cause a problem:
<a href="/logout">HTML Logout</a>
My first thought was that the wasn't closing the channel correctly when I logout via an Inertia link, but If that were the case I would expect Pusher to log 3 messages (1 for input message and 1 back out to each open channel right?), but it only logs 2.
Any thoughts on what might be going on here?
In case these are helpful:
bootstrap.js:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
//wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
//wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
//wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
//enabledTransports: ['ws', 'wss'],
});
channels.php:
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Vue component
<script setup>
import { onMounted } from 'vue';
import { usePage, Link } from '@inertiajs/vue3';
defineProps({
posts: {
type: Array,
}
});
const page = usePage();
onMounted(() => {
console.log('onMounted is triggerd' + crypto.randomUUID());
//listener for broadcast events via pusher and echo
Echo.private('App.Models.User.' + page.props.auth.user.id)
.notification((notification) =>{
//router.reload({ only: ['auth'] });
console.log(notification.id + " " + crypto.randomUUID() );
switch(notification.type) {
case 'App\Notifications\NewMention':
console.log('calling ' + notification.id );
page.props.auth.unreadNotificationsCount++;
break;
}
});
});
</script>
<template>
Test {{ $page.props.auth.unreadNotificationsCount }}
<Link href="/logout" method="get" as="button" type="button">Inertia Logout</Link>
<a href="/logout">HTML Logout</a>
</template>
Notification :
<?php
namespace App\Notifications;
use App\Models\Comment;
use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewMention extends Notification implements ShouldQueue
{
use Queueable;
protected $postable;
/**
* Create a new notification instance.
*/
public function __construct(Post|Comment $postable)
{
$this->postable = $postable;
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['database','broadcast'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Hi!')
->line('You have been mentioned in a post!.')
->action('View Notifications', url('/notifications'));
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
'user' => $this->postable->user->only(['username','avatar']),
'postable' => $this->postable->only(['id'])
];
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toBroadcast(object $notifiable): array
{
return [];
}
}
Please or to participate in this conversation.