Reputation: 125
I've created REST APIs with laravel passport and placed them on my subdomain i.e "api.abc.com". And I've a react js app which connects to it. Now, In order to add real-time messaging, I used "pusher" and "laravel echo".
React app can successfully connect to the pusher and I can see that every time on debug console. And where I send a message, It also gets stored in the database and on the pusher. But the corresponding laravel echo channel listener is not getting triggered. I've tried every variation but could not get this to work.
REST APIs are placed on the server and React APP is currently locally hosted. That's why I've set "encrypted" to "false".
APP//Events//NewMessage
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('messages.' . $this->message->conversation_id);
}
public function broadcastWith()
{
return ["message" => $this->message];
}
public function broadcastAs()
{
return 'chat';
}
}
Registering an event inside the Message store function
broadcast(new NewMessage($msg));
config//broadcasting.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => false,
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
routes//channels.php
<?php
use App\Conversation;
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast::channel('messages.{id}', function ($user, $id) {
$con = Conversation::findOrFail($id);
// return $user->id == $con->user_id || $user->id == $con->shop_owner_id;
return true;
});
From my REACT APP
import Pusher from "pusher-js";
import Echo from "laravel-echo";
import Cookies from "universal-cookie";
const cookies = new Cookies();
const options = {
broadcaster: "pusher",
key: "d4b9af39550bd7832778",
cluster: "ap2",
forceTLS: true,
encrypted: false,
//authEndpoint is your apiUrl + /broadcasting/auth
authEndpoint: "https://api.abc.com/broadcasting/auth",
// As I'm using JWT tokens, I need to manually set up the headers.
auth: {
headers: {
"X-CSRF-TOKEN": csrf_token,
Authorization: "Bearer " + cookies.get("access_token"),
Accept: "application/json"
}
}
};
const echo = new Echo(options);
And inside a selectConversation function, I've got the following code
echo.private("messages." + id).listen(".chat", data => {
console.log("rumman");
console.log(data);
});
I've also with the following:
echo.private("private-messages." + id).listen(".chat", data => {
console.log("rumman");
console.log(data);
});
But I was never able to see any console.log data.
Upvotes: 2
Views: 7733
Reputation: 196
Laravel sends events that are broadcasted to the queue. So you need to have some form of queue driver setup. Ideally, I will use Redis as my queue driver and can keep track of the events that are being dispatched by running this command php artisan queue:work --tries=3
Edit added : https://laravel.com/docs/7.x/queues#max-job-attempts-and-timeout
Upvotes: 2
Reputation: 21
Change ShouldBroadcast
to ShouldBroadcastNow
.
Your messages are being queued.
Upvotes: 2