Laravel Echo does not received message from channel - laravel

I stuck very bad . in real-time laravel(version 9) project using pusher for websocket.
backend can get message but problem is Echo does not received message which sent from backend ...
Event :
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message ;
public function __construct($message){
$this->message=$message;
}
public function broadcastOn()
{
\Log::debug("{$this->message}");
return new Channel('chat');
}
public function broadcatAs(){
return 'chat';
}
}
JS :
Echo.channel('.chat').listen('MessageSent', (e) => {
alert(e.message)
});
further information :
1- according to Event I can log message to laravel.log file which means message sent from frontend to backend .
2-there is no error in console area
3-see debug console of pusher official site

There are 3 issues I believe. The first is you should not need to do .chat in your channel function on the frontend. The second is you mispelled broadcastAs function as broadcatAs customizes the event that is being listened for in the frontend. However, because it is mispelled you are referring to the event correctly though if you update it you will then need to change your listener to .chat . The last issue is you may not have started your queue. You need to run a daemon to handle that.
Echo.channel('chat').listen('MessageSent', (e) => {
alert(e.message)
});
however, if you update your broadcastAs spelling correctly it will need to be
Echo.channel('chat').listen('chat', (e) => {
alert(e.message)
});

Related

Laravel Livewire Echo configuration

I've setup a notification system with Pusher and Echo on my Laravel 8 app. It works fine, I'm able to retrieve the notification event in VanillaJS with
window.Echo.private('App.Models.User.' + User.id)
.notification((notification) => {
if (notification.type === 'App\\Notifications\\JobLiked') {
let count = document.getElementById('count');
let number = count.innerHTML;
number++;
count.innerHTML = number;
}
});
But now I want to use Livewire listeners to trigger my function, then I setup :
public function getListeners()
{
return [
"echo-private:App.Models.User.{$this->authId},NotificationSent" => 'notifyNewJobLiked',
];
}
But nothing seems to work and I have no error message.. do you have any clue what could possibly going on ?
Thank you very much ! :)
Try to configure your listener with the following specific event name:
public function getListeners()
{
return [
"echo-private:App.Models.User.{$this->authId},.Illuminate\\Notifications\\Events\\BroadcastNotificationCreated" => 'notifyNewJobLiked',
];
}
Since you are using Laravel Notifications to trigger the broadcast instead of a broadcastable event, the event name when fired defaults to Illuminate\\Notifications\\Events\\BroadcastNotificationCreated.
In Echo there are two methods to listen for incoming messages: notification and listen. The reason why it works with your vanilla js is that you are using the notification method, whereas the livewire event listener only works with Echo's listen, which expects the name of the calling event.
If you are using pusher, you can see the name of the calling event in the pusher debug console.
Also take care and add a dot in front of the namespaced event as described in the documentation.
Right way to get Echo notification in livewire:
public function getListeners()
{
$user_id = auth()->user()->id;
return [
"echo-notification:App.Models.User.{$user_id}, notification" => 'gotNotification'
];
}
As you can see the channel type is notification, not private:
echo-notification
Also don't forget to have a record authenticating the users in your channels route, same as you do for a private channel:
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Another thing I learned is that you can get the notification channel data from the returned field.
So you can do:
public function gotNotification($notification)
{
}

Laravel - Pusher - Detect when a user is no longer in the website or leaves the page

I'm facing a problem with a real time app that i'm developing. My problem is about user's status using Pusher. I would like to get the correct way to detect when a user leaves the page or keep unactive for a while to set it's status to 'offline', for example. How could I achieve that? I'm almost sure that is not recommended develop this feature at client-side, it should be at server-side, but how? How can I ask to clients if they are still there? Should I create a command and run it wit cron? Are there any mechanism to let the server 'detect' the socket disconnection? Any help will be appreciated, Thx!
Update
With NoseJS and SocketIO it's really simple, you just have to write:
io.on('connection', function (socket) { // When client connects
socket.on('disconnect', function() { // Listen to disconnections from SERVER-SIDE
// Logic when a user disconnects. This is what I want!
});
});
But in Laravel, I only have this:
// A Laravel Event Class that implements the shouldBroadcast interface...
public function broadcastOn()
{
// I think here is where connections happen, but I don't know how to detect 'disconnections' :(
return new PresenceChannel('someString');
}
PD: I'm using Laravel Echo and Pusher :)
You can use presence channels to achieve this. You can then use presence webhooks to notify your server whenever a user enters or leaves the channel.
Simplest way is to subscribe to the the ConnectionClosed event
Providers/EventServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use BeyondCode\LaravelWebSockets\Events\ConnectionClosed;
use App\Listeners\OnConnectionClosed;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
ConnectionClosed::class => [
OnConnectionClosed::class
]
];
public function boot()
{
parent::boot();
}
}
Listeners/OnConnectionClosed.php
<?php
namespace App\Listeners;
use BeyondCode\LaravelWebSockets\Events\ConnectionClosed;
class OnConnectionClosed
{
public function handle(ConnectionClosed $connection)
{
if( !is_null($connection->appId) && !is_null($connection->socketId) ){
error_log($connection->appId);
error_log($connection->socketId);
}
}
}

How to rename Laravel Events when broadcasting to pusher?

When I am broadcasting events, I have to use the Laravel event names like:
this.pusherChannel.bind('App\\Events\\ServerCreated', function(message) {
console.log(message.user);
});
Is there a way, that I can rename events?
In Event definition file try:
/**
* The event's broadcast name.
*/
public function broadcastAs(): string
{
return 'server.created';
}
navigate to your event folder from app\envent and event ServerCreated in the class of ServerCreated put the following code under the function of broadcastWith
public function broadcastAs()
{
return 'my_custome_name';
}
this function will return your desired name to your pusher broadcasting event

Queueable entity App\Setting not found for ID error in Laravel

I am trying to send emails in laravel 5.1 by using queues. When running queue listen command on terminal,
php artisan queue:listen
Displays below error on terminal,
[Illuminate\Contracts\Queue\EntityNotFoundException]
Queueable entity [App\Setting] not found for ID [].
Values of jobs table is not process. Any idea ?
How can I process my queue ?
I know this question is a few months old, but I'd like to add an observation of mine while encountering this very same error message. It is due to the EventListener (interface of ShouldQueue in this example for asynchronous) not being able to resolve a dependant variable correctly (out of scope or not included in scope of Event object passed through the handle(Event $event) method of EventListener).
For me, this error was fired when I put my code within the __construct block within the EventListener:
public function __construct(Event $event)
{
$localProperty = $event->property
Mail::queue(etc...);
}
public function handle()
{
// Yeah I left this blank... whoops
}
Instead, the handle() method of the EventListener takes an Event interface and when called processes the job in the queue:
In the Event:
public function __construct(Object $ticket, AnotherObject $user)
{
$this->ticket = $ticket;
$this->user = $user;
}
And in Event Listener
class SomeEventListener implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public function __construct()
{
// Leave me blank!
}
public function handle(Event $event)
{
$someArray = [
'ticket' = $event->ticket,
'user' = $event->user,
];
Mail::queue('some.view', $someArray, function($email) use ($someArray) {
// Do your code here
});
}
}
Although a tad late, I hope this helps someone. Queues are similar to Events (with the exception of Jobs being the main driving force behind Queues), so most of this should be relevant.
Turned out that it was because a model was added to the queue, that has since been deleted.

Send email from queued event handler

I use Lumen 5.1 and Redis for queues. And I have a pretty standard event handler that should send an email:
<?php
namespace App\Handlers\Events;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Events\UserHasRegistered;
use Illuminate\Contracts\Mail\Mailer;
class SendWelcomeEmail implements ShouldQueue
{
protected $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function handle(UserHasRegistered $event)
{
$user = $event->user;
$this->mailer->raw('Test Mail', function ($m) use ($user) {
$name = $user->getFirstName().''.$user->getLastName();
$m->to($user->auth()->getEmail(), $name)->subject('This is a test.');
});
}
}
The email is sent when I don't use the ShouldQueue interface. But when I push the event handler to the queue (i. e. use the ShouldQueue interface), the email is not sent and I don't get any error messages.
Do you have any ideas how to solve or debug this?
It was not a bug, just an unexpected behaviour.
I am using Xampp on Windows and the php mail driver for development. For some reason the queued mails were not saved in the default mailoutput folder within the Xampp directory. Instead a new mailoutput folder was automatically created within the Lumen directory.
There I found all the missed mails. :)

Resources