The websocket isn't updating every time I send a message, so I have to refresh the browser before the message appears. I'm trying to establish one-to-one chat messages in my program, but there are issues.
I am using Laravel 9.48.0
Send Message Event
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class SendMessage implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
public $roomId;
public $fromId;
public $status;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($message,$user,$roomId,$fromId,$status)
{
$this->message = $message;
$this->user = $user;
$this->roomId = $roomId;
$this->fromId = $fromId;
$this->status = $status;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('message.'.$this->roomId);
}
public function broadcastAs()
{
return 'chat-message';
}
public function broadcastWith()
{
return [
'id'=>$this->fromId,
'name'=>$this->user,
'message'=>$this->message,
'status'=>$this->status,
];
}
}
channels.php
Broadcast::channel('chatroom', function ($user) {
return $user;
});
Broadcast::channel('App.Models.User.*', function ($user, $id) {
return (int) $user->user_id === (int) $id;
});
Broadcast::channel('message.{message_id}', function ($user, $id) {
return $user;
});
BroadcastServiceProvider
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
bootstrap.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Echo from 'laravel-echo';
console.log('hee');
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
Frontend
let token = $('meta[name="csrf-token"]').attr('content');
//form-id
let form = document.getElementById('form');
//input-message
let inputMessage = document.getElementById('input-message');
//container-message
let container = document.getElementById('container-message');
//room-id
let roomid = document.getElementById('room-id');
const roomId = roomid.value;
//other-user-id
let touserId =document.getElementById('touserId');
const toUserId = touserId.value;
let send = document.getElementById('send-btn');
let typing = document.getElementById('typing');
let status = document.getElementById('status');
let read_message = document.querySelectorAll('.fa-check-double.unreaded');
//array of online users in both sides
let usersOnline = [];
//create new channel and make pass room id to it
const channel = Echo.join(`message.${roomId}`);
//add status code 1 => online , 0 => offline
function add_status_code()
{
let status_code = 0
usersOnline.forEach(user => {
if(user.id == toUserId){
status_code = 1
}
});
return status_code
}
//check message status in front view
function check_message_status(message)
{
let status_t = 'unreaded'
if(message.status == 1){
status_t = 'readed'
}
return status_t
}
//create message
function create_message(message)
{
let status_t = check_message_status(message)
console.log(status_t)
console.log('aaamk');
var today = new Date();
var time = today.toLocaleTimeString();
if(message.id == '{{Auth::id()}}'){
container.innerHTML +=`
<div class="message text-only">
<div class="response">
<p class="text">${message.message}</p>
</div>
</div>
<p class="time my_time">${time} <i class="fa-sharp fa-solid fa-check-double ${status_t}"></i></p>
`
}else{
var today = new Date();
var time = today.toLocaleTimeString();
container.innerHTML +=`
<div class="message">
<div class="photo" style="background-image: url(https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80);">
<div class="online"></div>
</div>
<p class="text"> ${message.message} </p>
</div>
<p class="time">${time}</p>
`;
}
}
//read message in typing
function read_all_message()
{
usersOnline.forEach(user => {
if(user.id == toUserId){
let readedd = document.querySelectorAll('.fa-check-double.unreaded');
readedd.forEach(el=>{
el.className = 'fa-sharp fa-solid fa-check-double readed';
})
$.ajax({
method: "POST",
url: "/read_all",
data: {
toId: toUserId,
roomId: roomId,
_token: token
},
});
}
});
}
//show in typing
inputMessage.addEventListener('input',function(event){
if(inputMessage.value.length == 0){
channel.whisper('stop-typing');
}else{
channel.whisper('typing',{
name: "{{$user->name}}"
})
}
})
//on submit
form.addEventListener('submit',function(event){
const userInput = inputMessage.value;
event.preventDefault();
let status_code = add_status_code()
$.ajax({
method: "POST",
url: "/send",
data: {
message: userInput,
roomid:roomId,
touserId:toUserId,
status:status_code,
_token: token
},
});
channel.whisper('stop-typing');
inputMessage.value="";
})
channel.here((users)=>{
usersOnline = [...users]
console.log({usersOnline},'Here')
usersOnline.forEach(user => {
if(user.id == toUserId){
status.innerHTML = "Online";
}
});
})
.joining((user) => {
usersOnline.push(user);
console.log({usersOnline},'Join')
usersOnline.forEach(user => {
if(user.id == toUserId){
status.innerHTML = "Online";
}
});
})
.leaving((user) => {
usersOnline = usersOnline.filter((usersOnline)=> usersOnline.id !== user.id);
usersOnline.forEach(user => {
if (user.id != toUserId){
status.innerHTML = "Offline";
}
});
})
.listen('chat-message',(event)=>{
console.log('chat-message');
create_message(event)
})
.listenForWhisper('typing',(event)=>{
console.log('typing');
typing.innerHTML = "typing..";
read_all_message()
})
.listenForWhisper('stop-typing',(event)=>{
typing.innerHTML = "";
console.log('stop-typing');
})