1

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');


})

Aziz
  • 25
  • 6
  • 1
    Can you check if the `App\Providers\BroadcastServiceProvider:;class` is uncommented in `config\app.php` ? if it is commented you can uncomment it and try again. – xenooooo Feb 10 '23 at 12:15
  • Hello, @xenooooo. I'm not sure what I did, but it was fixed. However, the strange thing that is happening right now is that the web socket won't listen to changes. – Aziz Feb 10 '23 at 15:49

0 Answers0