lighthouse
lighthouse copied to clipboard
Subscription send only to others
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.
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
);
I never really worked with subscriptions and do not plan to work on it myself, but I am open for pull requests.
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