i had a problem when using presence channel in Laravel Echo with pusher. when I fire an event, i get 500 error from BroadcastException without the response body which is hard for me to debug it. when i look to pusher debug console, the presence event was listened by pusher. so i assume my event has never been fired to Pusher. Here is the preview in my network tab
my controller:
public function store() {
$user = auth()->user();
$message = $user->messages()->create([
'message' => request('message')
]);
event(new MessageReceived($message, $user));
return ['status' => 'OK'];
}
the MessageReceived class
namespace App\Events;
class MessageReceived implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Message $message, User $user)
{
$this->message = $message;
$this->user = $user;
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('chatroom');
}
}
and here is my vuejs
mounted() {
axios.get('/messages')
.then(response => {
this.messages = response.data
})
.catch(error => {
console.log(error)
})
Echo.join('chatroom')
.listen('MessageReceived', (e) => {
console.log(e) //never get into this
})
},
i can't find where the error is. i use cluster ap1 and is declared in broadcasting.php and in my bootstrap.js. anyone can help me out?
This can be caused by an error in your configuration. Here are some things to check:
In your .env file, make sure the pusher id, key, and secret are correctly set.
If you upgraded from Laravel 5.3 to Laravel 5.4, note that the .env variables PUSHER_KEY is now PUSHER_APP_KEY and PUSHER_SECRET is now PUSHER_APP_SECRET
In your config/broadcasting.php, make sure the cluster is set correctly.
If you are not in HTTPS, you may have to set the 'encrypted key to false
'options' => [
'cluster' => 'ap1', // change this to your app's cluster
'encrypted' => false,
],
Related
Hello I'm trying to make chat system for my app but I'm having problem making pusher and echo work. When I open my Chat between 2 people it does not update in real time and I have to refresh the page in order to get the updated stuff like messages and such. In console I'm getting these 2 errors
POST http://localhost/broadcasting/auth 403 (Forbidden)
POST http://localhost/broadcasting/auth 500 (Internal Server Error)
bootstrap.js
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true,
});
ChatBroadcast.php
class ChatBroadcast implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $ticket;
/**
* Create a new event instance.
*
* #param $ticket
*/
public function __construct(Ticket $ticket)
{
$this->ticket = $ticket;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('tickets_channel.' . $this->ticket->id);
}
public function broadcastWith(){
$messages = Message::all()->where('ticket_id','=',$this->ticket->id)->sortBy('created_at');
return [
'ticket' => $this->ticket,
'messages' => $messages
];
}
}
channels.php
use App\Ticket;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('tickets_channel.{ticketID}', function ($user, $ticketID) {
Auth::check();
$ticket = Ticket::all()->where('id', '=', $ticketID)->first();
return $ticketID == $ticket->id;
});
VueComponent
mounted() {
Echo.private('tickets_channel.${ticketID}')
.listen('ChatBroadcast', (e) => {
console.log(e);
this.messagesMutable = e.messages;
this.state = e.ticket.isOpened;
});
},
This is my log for 500 error
[2020-09-08 09:25:24] local.ERROR: Invalid channel name private-tickets_channel.${ticketID} {"userId":11,"exception":"[object] (Pusher\\PusherException(code: 0): Invalid channel name private-tickets_channel.${ticketID} at /Users/miroslavjesensky/Documents/Blog/vendor/pusher/pusher-php-server/src/Pusher.php:282)
-EDIT-
I have managed to fix the 500 error by changing VueComponent code to this
mounted() {
let id = this.ticket.id;
Echo.private('tickets_channel' + id)
.listen('ChatBroadcast', (e) => {
this.messagesMutable = e.messages;
this.state = e.ticket.isOpened;
});
},
Turns out the problem was with another VueComponent I am using with the first one. After fixing the listening part of echo there aswell all works as it should
I am attempting to broadcast a message via pusher in laravel but I am getting the following error:
Symfony\Component\Debug\Exception\FatalThrowableError · Too few arguments to function
App\Providers\BroadcastServiceProvider::{closure}(), 1 passed in
laravel/framework/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php on line 77 and exactly 2
expected routes/channels.php:33App\Providers\BroadcastServiceProvider::{closure}
});
The code that it's occuring on is the following
Broadcast::channel('conversations.{id}', function ($user, $id) {
return $user->inConversation($id);
});
I have another channel and it works fine
Broadcast::channel('users.{id}', function ($user, $id){
return (int) $user->id === (int) $id;
});
Not sure why there are too few arguments
*** UPDATE ***
I'm using laravel livewire.
The event class is as follows:
class MessageAdded implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* #param Message $message
*/
public function __construct(Message $message)
{
$this->message = $message;
}
public function broadcastWith()
{
return [
'message' => [
'id' => $this->message->id
]
];
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('conversations.' . $this->message->conversation->id);
}
}
The laravel livewire function is as follows:
public function reply()
{
$this->validate([
'body' => 'required'
]);
$message = $this->conversation->messages()->create([
'user_id' => auth()->id(),
'body' => $this->body
]);
$this->conversation->update([
'last_message_at' => now()
]);
foreach ($this->conversation->others as $user) {
$user->conversations()->updateExistingPivot($this->conversation, [
'read_at' => null
]);
}
broadcast(new MessageAdded($message))->toOthers();
$this->emit('message.created', $message->id);
$this->body = '';
}
Regards
Danny
Basically, the solution here was to set the Broadcast::routes in the BroadcastServiceProvider to the following
Broadcast::routes(['middleware' => 'auth']);
I tring add a chat extension to my web site , watched very much video lesson, Laravel and Pusher using user. Normally website is working
broadcasting(new MyEvent('my-event'));
but if I add line -before return line- , giving 500 Internal Server Error.
sended message is saving to DB but not return value...
Please help me
My ChatEvent.php
use App\Chat;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Broadcasting\PresenceChannel;
....
class ChatEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $chat;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Chat $chat)
{
$this->chat = $chat;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('chat');
}
}
My ChatController.php
use Illuminate\Http\Request;
use App\Chat;
use App\Events\ChatEvent;
class ChatController extends Controller
{
public function __construct(){
$this->middleware('auth');
}
public function index(){
return view('chat.chat');
}
public function fetchAllMessages(){
return Chat::with('user')->get();
}
public function sendMessage(Request $request){
$chat = auth()->user()->messages()->create([
'message' => $request->message
]);
broadcast(new ChatEvent($chat->load('user')))->toOthers();
return ['status' => 'success'];
}
}
VueJs Post And Get codes
<script>
export default {
methods: {
fetchMessages(){
axios.get('messages').then(response =>{
this.messages = response.data;
})
},
sendMessage(){
this.messages.push({
user: this.user,
message: this.newMessage
});
axios.post('messages',{message: this.newMessage});
this.newMessage='';
},
}
}
</script>
Routes and Channels
Route::get('/chats','ChatController#index');
Route::get('/messages','ChatController#fetchAllMessages');
Route::post('/messages','ChatController#sendMessage');
Broadcast::channel('chat', function ($user) {
return $user;
});
Pusher's AppKey,Secret,ID and Cluster OK,
Broadcaster-Driver: pusher Everywhere
I am getting a 403 on broadcasting/auth route.
I am using Laravel websockets package for web sockets and I have the below setup
- Backend Laravel server ( on port 8000 )
- Laravel Websockets Server ( laravel is running on 8001 and websocket server on 6001 )
- Standalone Ionic React app ( on port 8100)
Now everything works when I am trying Public Channel but when I try Private Channel it fails.
in the above screenshot of Laravel sockets dashboard I can see connection made as this is the same socketId which went with the request.
I am using Laravel Sanctum for Authentication.
PFB :- my client side code
const headers = {
'Content-Type': 'application/json',
Authorization: window.localStorage.getItem('token')
? `Bearer ${window.localStorage.getItem('token')}`
: '',
'Access-Control-Allow-Credentials': true,
};
const options = {
broadcaster: 'pusher',
key: 'abcsock',
authEndpoint: 'http://localhost:8001/api/broadcasting/auth',
authorizer: (channel, options) => {
return {
authorize: (socketId, callback) => {
axios
.post(
'http://localhost:8001/api/broadcasting/auth',
{
socket_id: socketId,
channel_name: channel.name,
},
{ headers, withCredentials: true }
)
.then((response) => {
callback(false, response.data);
})
.catch((error) => {
callback(true, error);
});
},
};
},
wsHost: '127.0.0.1',
wsPort: 6001,
encrypted: true,
disableStats: true,
enabledTransports: ['ws', 'wss'],
forceTLS: false,
};
Code from Laravel Websockets Server
api.php file
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Broadcast;
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Broadcast::routes(['middleware' => ['auth:sanctum']]);
BroadcastServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Broadcast::routes(['middleware' => ['auth:sanctum']]);
require base_path('routes/channels.php');
}
}
NewNotification.php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Broadcasting\PrivateChannel;
use App\AppNotification;
use App\User;
class NewNotification extends Notification
{
use Queueable;
public $notification;
public $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(AppNotification $notification, User $user)
{
$this->notification = $notification;
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast'];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
$notification = $this->notification;
return [
'id' => $notification->id,
'title' => $notification->title,
'description' => $notification->description,
'button_text' => $notification->button_text,
'is_read' => $notification->is_read,
'created_at' => $notification->created_at,
[
'notification_for' => $notification->notifiable
]
];
}
public function toBroadcast($notifiable)
{
return new BroadcastMessage($this->toArray($notifiable));
}
public function broadcastOn()
{
return new PrivateChannel('Notifications.' . $this->user->id);
}
}
channels.php
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('Notifications.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
}, ['guards' => ['sanctum']]);
I have attached whatever I felt was sufficient to explain the issue and for you to troubleshoot but if you need anything more please ask.
Any help will be appreciated
i liked this package because its wrote in php but its sortof abandon and a lot of issues that not solved.
alternative of this server is laravel-echo-server(as laravel docs recommends) very easier to use.
https://stackoverflow.com/a/61704796/7908390 more info if you can work with laravel-sockets im glad to see a new example
Have you added authentication for your channels.php? Please refer here:
https://laravel.com/docs/7.x/broadcasting#defining-authorization-routes
What does it look like?
I think you are doing everything correctly but you have not authorized your routes.
I had the similar error with Laravel & pusher.
I have fixed using decodeURIComponent and moving BroadCast::routes(['middleware' => ['auth:sanctum']]) to routes/api.php from BroadcastServiceProvider.php
Also, add withCredentials = true.
const value = `; ${document.cookie}`
const parts = value.split(`; XSRF-TOKEN=`)
const xsrfToken = parts.pop().split(';').shift()
Pusher.Runtime.createXHR = function () {
const xhr = new XMLHttpRequest()
xhr.withCredentials = true
return xhr
}
const pusher = new Pusher(`${process.env.REACT_APP_PUSHER_APP_KEY}`,
{
cluster: 'us3',
authEndpoint: `${process.env.REACT_APP_ORIG_URL}/grooming/broadcasting/auth`,
auth: {
headers: {
Accept: 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'X-XSRF-TOKEN': decodeURIComponent(xsrfToken)
}
}
})
I hope this helps a bit.
Im making a chat in my app and Im using pusher. I did everything that pusher told me to do. I'm using vanilla-js in frontend. I can connect in frontend. I can receiver messages from pusher (look at channel.bind()) but my messages are not going anywhere.
P.S I did all configuration (.env, broadcasting.php)
FRONTEND
var pusher = new Pusher('xxxxxxxx', {
cluster: 'eu',
forceTLS: false
});
window.channelName = 'my-channel-' + {{ $chat->id }};
window.event = 'private-conversation';
var channel = pusher.subscribe(window.channelName);
channel.bind(window.event, function (data) {
alert(data);
});
BACKEND
public function sendMessage($request, $roomId){
event(new Event(array(
'id' => auth()->user()->id,
'full_name' => auth()->user()->fullName()
), $request->input('channel'), $request->input('event'), $request->input('message')));
}
EVENT
class Event
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
public $message;
public $channelName;
public $event;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($user, $channelName, $event, $message)
{
$this->user = $user;
$this->channelName = $channelName;
$this->event = $event;
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return [$this->channelName];
}
public function broadcastAs()
{
return $this->event;
}
}