laravel / reverb

Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.
https://reverb.laravel.com
MIT License
1.12k stars 91 forks source link

Slow Performance #245

Closed cephasteom closed 2 months ago

cephasteom commented 2 months ago

Reverb Version

1.0.0

Laravel Version

11.16.0

PHP Version

8.2.21

Description

We are using a Laravel / Livewire / Reverb setup. We are using Reverb to communicate back to the Livewire front end components when a large job has been completed. These include downloading large media files, extracting frames etc. We have noticed that the round trip for Reverb is quite long.

To test this, I've dispatched a broadcast event from a Livewire component and noted the time, then listened for the response and calculated the elapsed time. The broadcast event itself simply generates a random number. Locally, on an M1 2021 Mac Book Pro, running the site on Valet, this takes anywhere from 0.5 to 3 seconds. When I deploy the site using Forge, this increases to 3 - 8 seconds - although this may be caused by the server being in the US and me being in the UK.

Do you have any insight into why this is so slow, and why the time taken varies so much?

Many thanks for you time.

Steps To Reproduce

Here's the code for a Livewire component that dispatches the event, and the event itself:

<?php

namespace App\Livewire\Testing;

use Livewire\Component;
use App\Events\WsTest;

class Testing extends Component
{
    public int $wsValue;
    public float $wsTime = 0;
    public float $wsStart = 0;

    public function getListeners()
    {
        return [
            "echo-private:testing,WsTest" => 'updateWsValue',
        ];
    }

    public function updateWsValue($value)
    {
        $this->wsTime = microtime(true) - $this->wsStart;
        $this->wsValue = $value['value'];
    }

    public function testWebsockets()
    {
        $this->wsStart = microtime(true);
        WsTest::dispatch();
    }

    public function render()
    {
        return view('livewire.testing.testing');
    }
}
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class WsTest implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     */
    public function __construct()
    {
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('testing'),
        ];
    }

    /**
     * Get the data to broadcast.
     *
     * @return array<string, string>
     */
    public function broadcastWith(): array
    {
        return [
            'value' => rand(1, 100)
        ];
    }
}
driesvints commented 2 months ago

Hi there,

Thanks for reporting but it looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repo you can try one of the following channels:

However, this issue will not be locked and everyone is still free to discuss solutions to your problem!

Thanks.

cAstraea commented 1 month ago

@cephasteom i'm also experiencing something similar 🤔 Was trying to test something similar to what Joe Dixon was presenting at Laracon where with a MessageReceived listener I'm broadcasting the message coming from the client when using Echo.connector.pusher.send_event('MessageEvent', JSON.stringify({userName, message, sendTimestamp}), 'chat.' + roomId);

But the response where I do sometihng like MessageEvent::dispatch($user, $channelName, $message, $sendTimestamp); takes 1.5 to 3 seconds in localhost. Tried different queues redis and DB image

joedixon commented 1 month ago

Are you ending up in a deadlock here?

If you try to broadcast an event from the listener, you are relying on something from the next tick of the loop which can't execute until the current tick completes which will never be able to happen.