Why I can not get message pusher in Laravel? - laravel

Here is a private channel:
public function broadcastOn()
{
// Here I get $user object successfully
return new PrivateChannel('user-'.$this->user->id); // it is 1
}
The permissions are:
Broadcast::channel('user-{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
The sender is:
Route::post('sender', function () {
PrivateEvent::dispatch(Auth::user());
})->middleware('auth:sanctum');
The client was tested in pusher debug console, it works:
var channel = pusher.subscribe('user-1');
channel.bind('PrivateEvent', function(data) {
alert(JSON.stringify(data));
});
Why when I send message using routing I dont get the message in JS? JS has not errors too.

Related

laravel broadcasting Broadcasting in private chanel not working i use laravel echo

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.

Create reactphp socket for push notification in laravel

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

Why I don't receive broadcast message Laravel Pusher?

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");
}

Private channels data does not get received by clients

I am not able to get private channels to work using Pusher and Laravel broadcasting. In the routes/channels.php file it seems that none of the function gets fired:
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('testevent.{id}', function ($user, $id)
{
//This never fires
dd("ENTERED HERE");
return TRUE;
});
In the BroadcastServiceProvider.php I have:
public function boot()
{
Broadcast::routes(['middleware' => 'auth:api']);
require base_path('routes/channels.php');
}
The Javascript file handling data on the client side (using Echo):
Echo.private('testevent.1').listen('TestEvent', function(e)
{
console.log(e);
});
Using public channels works perfect. But as soon as I try to create private channels the data is not sent to the client listening for the data. What could the problem be?
Thanks for any help and guidance!
EDIT:
In the Pusher web console it does not appear that the client has subscribed for the "testevent.1" channel. If I change this to a public channel the subscription gets registered.
At the "Defining authorization callbacks" paragraph of the Laravel Broadcast documentation, you can see that privates channels need to authenticate users before that they be able to listen to them.
So in in your routes/channels.php, you need there to write authentication logic, for exemple :
Broadcast::channel('testevent.{id}', function ($user, $id)
{
return $user->id === $user::findOrFail($id);
});

Pusher subscription error. Laravel

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

Resources