lighthouse icon indicating copy to clipboard operation
lighthouse copied to clipboard

Subscription send only to others

Open Stevemoretz opened this issue 2 years ago • 3 comments

https://laravel.com/docs/9.x/broadcasting#only-to-others

I think it is a really nice feature to have and it should be very simple to achieve it, since it's only a ready function that needs to be called.

What problem does this feature proposal attempt to solve?

When building an application that utilizes event broadcasting, you may occasionally need to broadcast an event to all subscribers to a given channel except for the current user.

Which possible solutions should be considered?

I think this feature is only for the Laravel Echo's broadcaster searching in your codebase I think I found where that method should be added: https://github.com/nuwave/lighthouse/blob/8756e1e5131aad489609eefd3424321d6cb76d99/src/Subscriptions/Broadcasters/EchoBroadcaster.php#L26

I noticed the autocompletion working there making this possible:

    public function broadcast(Subscriber $subscriber, $data): void
    {
        $this->broadcaster->event(
            new EchoSubscriptionEvent($subscriber->channel, $data)
        )->toOthers();
    }

Let me share my findings (haven't actually run the code just looked for now), this is the trace I did:

\Nuwave\Lighthouse\Execution\Utils\Subscription::broadcast

Going in:

/vendor/nuwave/lighthouse/src/Execution/Utils/Subscription.php

            if ($shouldQueue) {
                $broadcaster->queueBroadcast($subscription, $subscriptionField, $root);
            } else {
                $broadcaster->broadcast($subscription, $subscriptionField, $root);
            }

queue's job calls $broadcaster->broadcast again internally so let's see:

/vendor/nuwave/lighthouse/src/Subscriptions/SubscriptionBroadcaster.php
                $this->broadcastManager->broadcast(
                    $subscriber,
                    $this->graphQL->serializable($executionResult)
                );

Which leads to:

vendor/nuwave/lighthouse/src/Subscriptions/BroadcastManager.php

and there we find the echo driver:

vendor/nuwave/lighthouse/src/Subscriptions/Broadcasters/EchoBroadcaster.php

Inside that we'll reach https://github.com/nuwave/lighthouse/blob/8756e1e5131aad489609eefd3424321d6cb76d99/src/Subscriptions/Broadcasters/EchoBroadcaster.php#L26

So that should be it, we could pass along some data to the Queue Job and the other one, for an extra $toOthers and that can be used, it sounds like a pretty important feature that I still doubt whether this is already implemented and I missed it, nevertheless let me know what you think.

Stevemoretz avatar Feb 11 '23 17:02 Stevemoretz

Possible easier solution number 2

We know that Laravel uses socket_id in order to do the toOthers and you have a filtering feature (https://lighthouse-php.com/master/subscriptions/filtering-subscriptions.html)

And you have accessed socket_id for creating a unique id yourselves at /vendor/nuwave/lighthouse/src/Subscriptions/Broadcasters/EchoBroadcaster.php -> authorized

    public function authorized(Request $request): JsonResponse
    {
        $userId = md5(
            $request->input('channel_name')
            . $request->input('socket_id')
        );

So what if the Subscriber in filter function did contain the socket_id as well? Then in the simplest form this could work:

    public function filter(Subscriber $subscriber, $root): bool
    {
        return $subscriber->socket_id !== request()->input('socket_id');
    }

Obviously we could make it a little better in terms of usage (Extracting it to a function in parent and call that in a more elegant way) but this is just a concept for now.

How to implement

Again traced just by my eyes, we can change this class (Obviously)

vendor/nuwave/lighthouse/src/Subscriptions/Subscriber.php

And also it is filled only in one place:

vendor/nuwave/lighthouse/src/Subscriptions/SubscriptionResolverProvider.php

            $subscriber = new Subscriber(
                $args,
                $context,
                $resolveInfo
            );

Stevemoretz avatar Feb 11 '23 17:02 Stevemoretz

I never really worked with subscriptions and do not plan to work on it myself, but I am open for pull requests.

spawnia avatar Feb 13 '23 08:02 spawnia

I never really worked with subscriptions and do not plan to work on it myself, but I am open for pull requests.

Thanks for letting me know, I did manage to make it work also did a PR at https://github.com/nuwave/lighthouse/pull/2298

Stevemoretz avatar Feb 14 '23 14:02 Stevemoretz