I've been able to set up pusher and send, receive and respond to events on my local machine (docker using Laravel Sail). Each Livewire component across different pages responds to the event from pusher and does it's thing!
However, on my staging server only one component is responding to the event. The other fails to respond even though it appears the livewire component's event listener is configured the same. It fails whether I'm logged in as the same user (with 2 x browser tabs open to the page) or different users logged in from different devices.
in bootstrap.js I have:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Pusher.logToConsole = true;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true
});
In app.js I have
document.querySelector('#submit-button').addEventListener(
'click',
() => window.axios.post('/button/clicked')
);
// Subscribe to the public channel called "public-channel"
Echo.channel('golfbuddies-tour-development')
// Listen for the event called "button.clicked"
.listen('.ButtonClicked', (e) => {
console.log('event received:1', e);
});
I've added a button to fire the event whilst trying to debug this issue.
I've checked my .env and have all the correct pusher credentials set up on the local and staging server. I can see from the console pusher events are being sent and received (and I know one component is responding to the event.
This is the abridged version of the working component:
<?php
namespace App\Livewire\Leagues\Stableford;
use App\Events\ButtonClicked;
use App\Models\League;
use App\Wedleague\Eclectic\Data\StablefordLeagueTableData;
use App\Wedleague\Handicap\HandicapCalculator;
use App\Wedleague\Utility\StablefordCalculator;
use Flash;
use Gate;
use Livewire\Component;
use Log;
class Livescore extends Component
{
public $league;
public $scores = [];
public $handicaps;
public $courseHoles;
public $points = [];
public $players;
private $handicapHelper;
private $stablefordCalculator;
private $leaderboard;
protected $listeners = ['echo:channel-name,.ButtonClicked' => 'updateLeaderboard()'];
public function mount(League $league, int $group)
{
$this->league = $league;
$this->players = $this->league->getPlayersByGroup($group);
if (!Gate::allows('access-competition', $this->league->competition)) {
Flash::error('You are not a player in this competition and cannot score');
return redirect()->route('competitions.show', $this->league->competition->id);
}
$this->setExistingScores();
$this->handicapHelper = app(HandicapCalculator::class);
$this->handicaps = $this->players->mapWithKeys(function ($player) {
return [$player->id => $this->handicapHelper->getHandicap($this->league, $player)];
});
$this->courseHoles = $this->league->golfCourse->courseHoles()->get();
}
public function render()
{
$this->updateLeaderboard();
return view('livewire.leagues.stableford.livescore', [
'scores' => $this->scores,
'players' => $this->players,
'leaderboard' => $this->leaderboard,
]);
}
private function updateLeaderboard()
{
Log::info('Updating Leaderboard in liveScore ' . auth()->user()->first_name);
$leaderboard = app(StablefordLeagueTableData::class);
$leaderboard->initializeLeagueData($this->league);
$this->leaderboard = $leaderboard->getLeagueData();
}
public function mimicScoreEntry()
{
ButtonClicked::dispatch('Hello world!');
}
}
and this is an abridged version of the non-working component (that does work on the local machine)
<?php
namespace App\Livewire;
use App\Wedleague\LeagueViewDataPackage\LeagueViewDataPackageFactory;
use Livewire\Component;
use Log;
use App\Events\ButtonClicked;
class StablefordLiveLeagueTable extends Component
{
public $league;
public $courseHoles;
private $stablefordLeague;
protected $listeners = ['echo:channel-name,.ButtonClicked' => 'refreshLeague()'];
public function refreshLeague(): void
{
Log::info('Updating Leaderboard in LiveView ' . auth()->user()->first_name);
$this->dispatch('$refresh');
}
public function render()
{
$leagueTable = new LeagueViewDataPackageFactory;
$viewData = $leagueTable->build($this->league);
$data = $viewData->make()
->display('show')
->getViewData();
$this->stablefordLeague = $data['stablefordLeague'];
$this->courseHoles = $data['courseHoles'];
return view('livewire.stableford-live-league-table')
->with('league', $this->league)
->with('courseHoles', $this->courseHoles)
->with('stablefordLeague', $this->stablefordLeague);
}
}
and the Laravel event:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Log;
class ButtonClicked implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*/
public function __construct($message)
{
Log::info('ButtonClicked event fired');
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new Channel('channel-name'),
];
}
public function broadcastWith(): array
{
return [
'message' => $this->message,
];
}
// public function broadcastAs(): string
// {
// return 'button.clicked';
// }
}
I've removed the real channel name but have checked it's consistent. I've commented out the broadcastAs() as that caused an error earlier in development but should not be related to the issue.
In my console I see:
Pusher : : ["Event recd",{"event":"App\\Events\\ButtonClicked","channel":"channel-name","data":{"message":"Hello world!"}}]
My log file only shows the event message from Livescore component
I'm not sure what could be different on each server (local and staging) to create this issue. I see no errors in the log file and can see messages that the event is fired. I can also see the job being processed by Horizon on the staging server.
Where to start to get all components working and responding to the event?