laravel / reverb

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

When using `scaling` = `true` the `toOthers` method in Laravel does not work #246

Open gofish543 opened 1 week ago

gofish543 commented 1 week ago

Reverb Version

1..0

Laravel Version

11.21

PHP Version

8.3

Description

In the code block below the $connection variable of the dispatch function is ignored when using the PubSubProvider->publish(...). This is more of a question than a bug report, why is this the case and is there a way to get the PubSubProvider to properly ignore the passed $connection?

<?php

namespace Laravel\Reverb\Protocols\Pusher;

use Illuminate\Support\Arr;
use Laravel\Reverb\Application;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Protocols\Pusher\Contracts\ChannelManager;
use Laravel\Reverb\ServerProviderManager;
use Laravel\Reverb\Servers\Reverb\Contracts\PubSubProvider;

class EventDispatcher
{
    /**
     * Dispatch a message to a channel.
     */
    public static function dispatch(Application $app, array $payload, ?Connection $connection = null): void
    {
        $server = app(ServerProviderManager::class);

        if ($server->shouldNotPublishEvents()) {
            static::dispatchSynchronously($app, $payload, $connection);

            return;
        }

        // Enabled by `scaling = true` and does not take the $connectiton variable and therefore ignores `toOthers()`
        app(PubSubProvider::class)->publish([
            'type' => 'message',
            'application' => serialize($app),
            'payload' => $payload,
        ]);
    }

    /**
     * Notify all connections subscribed to the given channel.
     */
    public static function dispatchSynchronously(Application $app, array $payload, ?Connection $connection = null): void
    {
        $channels = Arr::wrap($payload['channels'] ?? $payload['channel'] ?? []);

        foreach ($channels as $channel) {
            unset($payload['channels']);

            if (! $channel = app(ChannelManager::class)->for($app)->find($channel)) {
                continue;
            }

            $payload['channel'] = $channel->name();

            $channel->broadcast($payload, $connection);
        }
    }
}

Steps To Reproduce

1) Create a Laravel app with a Broadcasting event 2) Broadcast the even toOthers 3) Ensure reverb is set to scaling = true 4) Observe toOthers is ignored by reverb server

joedixon commented 1 week ago

I'll take a look at this soon.

gofish543 commented 1 week ago

I'll take a look at this soon.

It's really just a technical question relating to the PubSubProvider::class and if it's implementation / use in scaling mode can even support toOthers. At the end of day, it causes an extra round trip request form my client application and isn't critical... more of a micro optimization / papercut :)