My event broadcast looks as:
class OrderStatusUpdate implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $username;
public $message;
public function broadcastAs()
{
return 'my-event';
}
public function __construct($username)
{
$this->username = $username;
$this->message = "Order status by {$username} was changed";
}
public function broadcastOn()
{
return ['my-event'];
}
}
Call event like:
Route::get('/', function () {
OrderStatusUpdate::dispatch('Nick');
return "Event has been sent!";
});
Client side is:
var pusher = new Pusher('018814b79958ee4f2ad1d', {
cluster: 'eu',
forceTLS: true
});
var channel = pusher.subscribe('my-event');
channel.bind('my-event', function(data) {
alert(JSON.stringify(data));
});
All .env settings are correct!
As you can see I use default Laravel settings and channel name. But message comes with error in Pusher server. But I dont get them on HTML page, with code JS showed upper.
Let me explain from client side:
var channel = pusher.subscribe('order');
channel.bind('OrderStatusUpdate', function(data) {
alert(JSON.stringify(data));
});
order id name of channel
OrderStatusUpdate is event name Event
It mean server should be:
public function broadcastAs()
{
return 'OrderStatusUpdate'; // Event name
}
public function broadcastOn()
{
return ['order'];
}
But I am not sure about this array sintax: return ['order'];, try instead this:
public function broadcastOn()
{
return new Channel("order");
}
Related
I tried to listen event emited from broadcast in laravel livewire but nothing happen;
on my bootstrap.js i have:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'myKey',
wsHost: window.location.hostname,
wsPort: 6001,
disableStat: true,
forceTLS: false,
});
my event laravel
class TaskFinished implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct()
{
//
}
public function broadcastAs(){
return 'task-finish';
}
public function broadcastOn()
{
return new Channel('TaskTricolor');
}
}
my listener
class SendTaskNotif
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param TaskFinished $event
* #return void
*/
public function handle(TaskFinished $event)
{
}
}
and my livewire component
protected $listeners = ['echo:TaskTricolor,TaskFinished' => 'eventlisten'];
// public function getListeners(){
// return [
// 'echo:TaskTricolor,TaskFinished' => 'eventlisten'
// ];
// }
public function start(){
$this->start = true;
$tricolors = new TricolorController();
$this->tricolor = $tricolors->start();
}
public function stop(){
$this->start = false;
$tricolors = new TricolorController();
$this->tricolor = $tricolors->stop();
}
public function emet(){
event(new TaskFinished());
}
public function eventlisten(){
$vars = "test";
dd($vars);
}
on my listener i put dd('test') and when the emet function is called, the dd value is showed;
So when i test with livewire listener handler, nothing happen, my dd not appear, and no error;
I tried to console log Echo from blade to test if i can handle listener, but it show that Echo is not defined, but when i console.log window, i see Echo inside
On my websocket dashboard i have this:
I don't know if it can help to solve, i use beyondcode/laravel-websockets package as driver
When I first started to use Livewire (version 1.0) we listened the messages using vanilla javascript and then called the Livewire.
document.addEventListener("DOMContentLoaded", function () {
window.Echo.private('TaskTricolor')
.listen('.task-finish', (response) => {
window.Livewire.emit('task-finish', response));
}
});
You can try this. It's not a clean solution as your approach, but I think is easier to debug.
I found the issue; on my event class i should use ShouldBroadCastNow instead ShouldBroadCast
class TaskFinished implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct()
{
//
}
public function broadcastAs(){
return 'task-finish';
}
public function broadcastOn()
{
return new Channel('TaskTricolor');
}
}
the ShouldBroadCast put the event in queue, so it's not activated on event called, but ShouldBroadCastNow listen the event immediately, here link i found the explanation
add metadata in your template
<meta name="csrf-token" content="{{ csrf_token() }}">
declare token in your boostrap.js
let token = document.head.querySelector('meta[name="csrf-token"]');
window.Echo = new Echo({
broadcaster: 'push',
.....
...
auth: {
headers: {
Authorization: 'Bearer' + token,
},
},
and call event with
document. addEventListener("DOMContentLoaded", function () {
window.Echo.private('TaskTricolor')
.listen('.task-finish', (response) => {
window.Livewire.emit('task-finish'));
}
});
event is:
public $chat ;
public function __construct($chat)
{
$this->chat = $chat;
}
public function broadcastOn()
{
// return new Channel('recieve-chat');
return new PrivateChannel('recieve-chat' );
}
routes/channels.php is:
Broadcast::channel('recieve-chat', function ($user ) {
return true;
// return $user->id === $reciever_id;
});
in blade file:
<script>
window.addEventListener('DOMContentLoaded' , function () {
Echo.private('recieve-chat')
.listen('ChatBroad', (e) => {
window.livewire.emit('recieve:' + e.chat.bid_id , e.chat);
$(chatScrollDown('.chat'+ e.chat.bid_id ));
});
});
</script>
broadcast Channel work properly. but in PrivateChannel is not working. and in console not showing any error
i use laravel echo and pusher
in App\Providers\BroadcastServiceProvider.php
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
must like the code. in Broadcast::routes() we dont need any middleware.
I want to use reactphp socket for push notifications in laravel but I do not know what to do?
route:
Route::get('/test', function () {
event(new testEvent($test));
});
event:
public $test;
public function __construct($test)
{
$this->test = $test;
}
public function broadcastOn()
{
return new PrivateChannel('test.' . $this->test->id);
}
channel:
Broadcast::channel('test.{test}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Note: I do not want to use the pusher
I'm trying to setup broadcast just like laravel documentation. I'm using pusher.
Here is my FriendRequestSent event:
class FriendRequestSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $id;
public function __construct($id)
{
$this->id = $id;
}
public function broadcastOn()
{
return new Channel('friend-request.' . $this->id);
}
}
And I call it like this:
event(new FriendRequestSent("5a22f7e72e069a2e64001ed5"));
Here is my channel.php
Broadcast::channel('friend-request.{receiverId}', function ($user, $receiverId) {
return true;
});
and this is my script on the page:
<script>
Echo.private(`friend-request.${receiverId}`)
.listen('FriendRequestSent', (e) => {
console.log(e);
});
</script>
Just like documentation. But I get this error in browser's console:
Uncaught ReferenceError: receiverId is not defined.
Could anyone help?
I'm trying to make a chat between two persons in Laravel 5.4 with Pusher.
First, I send an Ajax post request:
$('#btn-chat').click(function (){
$.post('sendMessage',{
_token: $("[name='csrf-token']").attr('content'),
user_id: userId,
chat_id: 1,
message: $('#btn-input').val()
},
function(data) {
console.log(data);
});
});
Then, a controller takes the request:
public function sendMessage(Request $request){
$user = Auth::user();
$message = new Message;
$message->fill($request->all());
$message->message = $request->message;
$message->save();
broadcast(new MessageSent($message))->toOthers();
return 'Return MessageController';
}
Also, here is my MessageSent event:
class MessageSent implements ShouldBroadcast {
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public function __construct($message) {
$this->message = $message;
}
public function broadcastOn() {
return new PrivateChannel('chat.'.$this->message->chat_id);
}
}
And my channels.php document:
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('chat.*', function ($user, $chat_id) {
return (int) $user->id === (int) $chat_id;
});
And finally, the JavaScript listens to events:
var pusher = new Pusher('pusher_key', {
cluster: 'us2',
encrypted: true,
authEndpoint: 'broadcasting/auth',
auth: {
headers: {
'X-CSRF-Token': $("[name='csrf-token']").attr('content')
}
}
});
Pusher.logToConsole = true;
var channel = pusher.subscribe('private-chat.1');
channel.bind('MessageSent', (data) => {
alert(data.message);
});
All that should to the work, but when I load the chat page, it throws an error on JavaScript console:
Pusher : No callbacks on private-chat.1 for pusher:subscription_error
Pusher emits events automatically in certain circumstances.
Pusher : No callbacks on private-chat.1 for pusher:subscription_error
Is telling you that there was an error subscribing to the channel, but you haven't bound a callback to that event. You should be able to get more information about the error you experienced during subscription by binding to the subscription:error event. You can find more info here.
As leesio anwsered, Pusher emits events if an error ocurrs.
Afther I added:
channel.bind('pusher:subscription_error', function(data) {
console.log(data);
});
It displayed in console:
JSON returned from webapp was invalid, yet status code was 200.
Because the Laravel broadcasting routes (broadcasting/auth) returned an HTTP response, not the JSON that Pusher needs.
So my solution was create a new route (pusherAuth), and then returning to Pusher the following JSON:
public function pusherAuth(Request $request){
$key = 'xxxxxxxxxxxxx';
$secret = 'xxxxxxxxxxxxxx';
$channel_name = $request->channel_name;
$socket_id = $request->socket_id;
$string_to_sign = $socket_id.':'.$channel_name;
$signature = hash_hmac('sha256', $string_to_sign, $secret);
return response()->json(['auth' => $key.':'.$signature]);
}
Client-side JavaScript:
var pusher = new Pusher('xxxxxxxxxxxxx', {
cluster: 'us2',
encrypted: true,
authEndpoint: 'pusherAuth', //Before 'broadcasting/auth'
auth: {
headers: {
'X-CSRF-Token': $("[name='csrf-token']").attr('content')
}
}
});
And that should do the work. I don't know why I couldn't do it with Laravel broadcasting routes, but I post this answer if anyone has the same problem.
More info:
Pusher auth signatures
PHP HMAC SHA56