'Laravel Echo does not listening

I'm trying to create a simple chat system using socket.io and Laravel Echo. Unfortunately I cannot make this working, Laravel Echo doesn't listen to any events.

First of all I have added two new containers in my docker-compose.yml, one for redis and another for laravel-echo-server:

redis:
  image: 'redis:alpine'
  ports:
    - '6379:6379'
  volumes:
    - './docker/redis:/data'
  healthcheck:
    test: [ "CMD", "redis-cli", "ping" ]
    retries: 3
    timeout: 5s

node:
  image: node:latest
  container_name: socialthess_node
  links:
    - redis:redis
  ports:
    - 3000:3000
  volumes:
    - ./src:/usr/src/app
    - /home/data/certs/example.com.crt/:/etc/node/ssl/cert.crt
    - /home/data/certs/example.com.key/:/etc/node/ssl/cert.key
  command: bash -c "npm install --unsafe-perm -g laravel-echo-server && cd /usr/src/app && laravel-echo-server start"

Configuration for laravel-echo-server.json:

{
    "authHost": "https://nginx",
    "authEndpoint": "/broadcasting/auth",
    "clients": [],
    "database": "redis",
    "databaseConfig": {
        "redis": {
            "port": "6379",
            "host": "redis"
        }
    },
    "devMode": false,
    "host": "0.0.0.0",
    "port": "3000",
    "protocol": "https",
    "socketio": {},
    "sslCertPath": "/etc/node/ssl/cert.crt",
    "sslKeyPath": "/etc/node/ssl/cert.key"
}

When I start the app I can see that laravel-echo-server is working fine:

enter image description here

I've included the following within bootstrap.js:

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':3000'
})

and the header I've added this line to load the socket package from the container:

<script src="{{ config('app.url') }}:3000/socket.io/socket.io.js"></script>

So when I load the browser console I can see this:

enter image description here

Even the socket call created by the Echo client seems to working fine:

enter image description here

In my application I have enabled the BroadcastServiceProvider::class available within config/app.php.

Then, in the .env file I set redis as BROADCAST_DRIVER.

I've created a channel route to broadcast the available rooms of the chat:

src/routes/channels.php

Broadcast::channel('room.{id}', function ($user, $id) {
    return $user->id;
});

Also, I have the following routes within src/routes/web.php:

Route::middleware(['auth'])->group(function () {
    Route::get('/chats', [ChatsController::class, 'index'])->name('chats.index');
    Route::post('/messages', [MessagesController::class, 'sendMessage'])->name('messages.send');
});

In order to not create confusion, I will only show the sendMessage method of MessagesController:

public function sendMessage(Request $request)
{
    $request->validate([
        'roomId' => ['required'],
        'message' => ['required', 'string', 'max:140'],
    ]);
    $user = $request->user();
    $room = Room::findOrFail($request->roomId);
    $message = $user->messages()->create([
        'room_id' => $room->id,
        'message' => $request->message,
    ]);
    broadcast(new MessageSent($user, $room, $message))->toOthers();
    return Response::json(['ok' => true]);
}

When an user send a message, the sendMessage is called and the MessageSent event is fired:

<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\Boilerplate\User;
use App\Models\Room;
use App\Models\Message;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    /**
     * @var \App\Models\User
     */
    protected $user;
    /**
     * @var \App\Models\Room
     */
    protected $room;
    /**
     * @var \App\Models\Message
     */
    protected $message;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user, Room $room, Message $message)
    {
        $this->user = $user;
        $this->room = $room;
        $this->message = $message;
    }
    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel("room.{$this->room->id}");
    }
    /**
     * Broadcast with specific data.
     * 
     * @return array
     */
    public function broadcastWith()
    {
        return array_merge($this->message->toArray(), ['user' => $this->user->only('id', 'name')]);
    }
}

The call is maded by pressing the send button:

$('#send-message').on('click', function() {
    $.ajax({
        type: 'POST',
        url: '{{ route('messages.send') }}',
        data: {
            'roomId': `{{ $room->id }}`,
            'message': $('#message').val(),
        },
        success: function(data) {
            console.log(data)
        },
        error: function(e) {
            console.log(e)
        }
    })
})

Then, whithin the blade file I have this line:

@push('js')
    <script>
        $(document).ready(function() {

            window.Echo.join(`room.{{ $room->id }}`)
                .here((users) => {
                    console.log(users);
                })
                .joining((user) => {
                    console.log(user);
                })
                .leaving((user) => {
                    console.log(user);
                })
                .error((error) => {
                    console.log('echo:error', error);
                })
                .listen('MessageSent', (e) => {
                    console.log(e);
                })
                .listenForWhisper('typing', (user) => {
                    console.log('typing user => ', user);
                })
        })
    </script>
@endpush

That is supposed to show the messages sent over the room channel, but for some reason I get no response. I also tried to add a . in front of MessageSent but same situation.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source