I'm implementing a Vue messaging component inside my laravel application. Messages are being successfully sent to Pusher as seen in the debug console but I've been struggling for three days to get laravel to listen so users on the same private channel can receive messages.
This is based on this app on github https://github.com/AfikDeri/Messenger-App-VueJS-and-Laravel
I have double-checked all key areas of the code that may be at fault but can't find the issue.
Have cleared cache and config in Laravel and recompiled Javascript code multiple times. I'm testing on XAMPP Version: 7.2.12 / windows 7.
Have tried turning off Windows firewall and Avast Antivirus.
Messages are being received in the Pusher debug console and are also being added to the database via axios and sent back to the sending client application and pushed onto the sender's message array. They just aren't been seen by the recipient and I'm not seeing any trace of event broadcasting in chrome.
ChatApp.vue
<template>
<div class="chat-app">
<conversation :contact="selectedContact" :messages="messages" @new="saveNewMessage"></conversation>
<contacts-list :contacts="contacts" @selected="startConversationWith"></contacts-list>
</div>
</template>
<script>
export default{
props:{
user:{
type: Object,
required:true
}
},
data(){
return{
selectedContact: null,
messages: [],
contacts: [],
}
},
mounted(){
Echo.private(`messages.${this.user.id}`)
.listen('NewMessage', (e) => {
// console.log('Broadcast received.');
this.handleIncoming(e.message);
});
axios.get('/contacts')
.then((response) => {
console.log(response.data);
this.contacts = response.data;
});
},
methods:{
startConversationWith(contact){
axios.get(`/conversation/${contact.id}`)
.then((response) =>{
this.messages = response.data;
this.selectedContact = contact;
}
)
},
saveNewMessage(message){
this.messages.push(message);
},
handleIncoming(message) {
alert(JSON_stringify(message));
if (this.selectedContact && message.from_id == this.selectedContact.id) {
this.saveNewMessage(message);
return;
}
},
}
}
</script>
In App\Events\NewMessage.php
namespace App\Events;
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;
public function __construct(Message $message)
{
$this->message = $message;
}
public function broadcastOn()
{
return new PrivateChannel('messages.' . $this->message->to_id);
}
public function broadcastWith()
{
$this->message->load('fromContact');
return ["message" => $this->message];
}
}
in 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,
key: '455936d5b071dd92ef25',
cluster: 'us3',
encrypted: false
});
require('./echo');
console.log(window.Echo.options);
in App/config/app.php
Illuminate\Broadcasting\BroadcastServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
// Are uncommented
in BroadcastServiceProvider
public function boot()
{
// Broadcast::routes();
/*changed this to fix a pusher auth error
only prob is it routes pusher to /home after authentication but without error */
Broadcast::routes(['middleware' => 'auth']);
require base_path('routes/channels.php');
}
in channels.php :
Broadcast::channel('messages.{$id}', function ($user, $id) {
//dd($user->id, $id);
return $user->id === (int) $id;
});
In the ContactController
public function send(Request $request){
$message = new Message();
$message->from_id = auth()->user()->id;
$message->to_id = $request->contact_id;
$message->text = $request->text;
$message->conversation_id = 1;
if($message->save()) {
broadcast(new NewMessage($message));
return response()->json($message);
}
else{
return response()->json('failed');
}
In chrome > I am seeing these messages
Pusher : State changed : connecting -> connected with new socket ID 52.5078004
registerEventsMessage called
//I think the next error is when I refreshed the browser forcing the Vue app to reconnect.
{event: "pusher:error", data: {code: 4009, message: "Connection not authorized within timeout"}}
data: {code: 4009, message: "Connection not authorized within timeout"}
event: "pusher:error"
//This appeared initially but not when messages were sent
No callbacks on presence-chat for pusher:subscription_error
No callbacks on private-messages.14 for pusher:subscription_error
The chat application should update in the recipients chat stream when a new message is sent to their channel but nothing happens. I'm not seeing any errors in the chrome console. User ids and dynamic channel names appear to be rendering correctly.
I do see this error when I refresh the browser but after that messaging appears to work normally. No errors show in the pusher console and I can see all messages are received there.
I'm relatively new to Laravel and Vue Would greatly appreciate any assistance or guidance on how to troubleshoot.