Fix: Store broadcast channels on BroadcastManager to ensure coroutine-safe authorization#286
Conversation
…-safe authorization
|
Hi @binaryfire , thank you for reporting this issue. I'm thinking, compared to moving the channel logic to BroadcastManager, would it be simpler to make the channel-related properties in Broadcaster static? By making these properties static: protected static $channels = [];
protected static $channelOptions = [];This way, besides avoiding method overlap with the original broadcaster methods, we can also maintain the original functional definition of the broadcaster as much as possible. The authorization logic ( Additionally, we could add a new public static function flushChannels(): void
{
static::$channels = [];
static::$channelOptions = [];
}What do you think? |
|
@albertcht That's much better. Don't know why I didn't think of that - it's so obvious. I've made the changes and added a test. The tests pass locally, but it looks like there was an error in the CI pipeline. Could you have a look and see what the problem is? |
…asterInstances` function
…asterInstances` function
|
Hi @binaryfire, the original error stemmed from a conflict that occurred when the |
Problem
When using pooled broadcast drivers (Pusher, Ably), channel authorization fails with 403 errors because channels registered via
Broadcast::channel()are proxied through__call()to individual pooled driver instances.In a coroutine environment:
Broadcast::channel('App.Models.User.{id}', ...)is called at boot time → registers on pooled instance ABroadcast::auth()proxied to pooled instance B (empty channels array)Solution
Store channels directly on the singleton
BroadcastManagerinstead of proxying to pooled drivers:This ensures all channel registrations are shared across all pooled broadcaster instances while maintaining the performance benefits of connection pooling.
Changes
Breaking Changes
None. All existing methods and behavior are preserved. The fix only affects how channels are stored internally.