VOOZH about

URL: https://deepwiki.com/hypervel/components/8-broadcasting-and-real-time-communication

⇱ Broadcasting and Real-Time Communication | hypervel/components | DeepWiki


Loading...
Last indexed: 7 March 2026 (96fbab)
Menu

Broadcasting and Real-Time Communication

This document covers the broadcasting system for real-time event dispatch to WebSocket clients. The system provides a driver-based architecture for sending events to various broadcasting services (Pusher, Ably, Redis, etc.) with support for channel authentication, event queuing, and connection pooling.

For details on specific broadcaster drivers and connection pooling, see Broadcasting Architecture and Drivers. For channel authentication mechanisms and user authorization, see Channel Authentication and Authorization. For event broadcasting patterns and anonymous events, see Event Broadcasting and Anonymous Events.

Purpose and Scope

The broadcasting system enables applications to push real-time updates to connected clients through WebSocket connections. It abstracts the underlying broadcasting service (Pusher, Ably, Redis, etc.) behind a unified interface, allowing developers to broadcast events without coupling to a specific provider. The system integrates with Hypervel's queue and event dispatcher for asynchronous event delivery and supports multiple channel types (public, private, presence) with authentication and authorization.

System Architecture

The broadcasting system follows the Manager pattern with driver resolution, connection pooling for external services, and integration with the queue system for asynchronous broadcasts.


Sources: src/broadcasting/src/BroadcastManager.php1-464 src/broadcasting/src/Broadcasters/Broadcaster.php1-304 src/broadcasting/src/BroadcastPoolProxy.php1-44 src/broadcasting/src/PendingBroadcast.php1-51 src/broadcasting/src/AnonymousEvent.php1-154

Core Components

BroadcastManager

The BroadcastManager class serves as the central factory for resolving broadcast drivers and managing connections. It implements the Manager pattern with driver caching and connection pooling.

MethodPurpose
driver(?string $name)Resolve a broadcaster driver by name
connection(?string $driver)Alias for driver()
queue(mixed $event)Queue an event for broadcasting
on(array|Channel|string $channels)Begin anonymous broadcast
private(string $channel)Begin private channel broadcast
presence(string $channel)Begin presence channel broadcast
routes(array $attributes)Register authentication routes
socket(?RequestInterface $request)Extract socket ID from request
extend(string $driver, Closure $callback)Register custom driver

The manager uses the HasPoolProxy trait to wrap Pusher and Ably drivers in connection pools, improving performance by reusing HTTP connections.

Sources: src/broadcasting/src/BroadcastManager.php36-464

Broadcaster Abstract Base

The Broadcaster abstract class provides shared functionality for all broadcaster implementations, including channel authentication, user retrieval with multiple guards, and parameter extraction for channel wildcards.

MethodPurpose
channel(string $channel, callable $callback, array $options)Register channel authenticator
auth(RequestInterface $request)Authenticate channel access
broadcast(array $channels, string $event, array $payload)Broadcast event (abstract)
resolveAuthenticatedUser(RequestInterface $request)Resolve user for Pusher/Ably auth
verifyUserCanAccessChannel(RequestInterface $request, string $channel)Check authorization

Channels are stored in a static $channels array shared across all broadcaster instances, allowing registration during application boot and access during authentication requests.

Sources: src/broadcasting/src/Broadcasters/Broadcaster.php23-304

Supported Broadcast Drivers

The system supports multiple broadcasting backends through a unified interface:

DriverClassConnection TypePooling
pusherPusherBroadcasterHTTP APIYes
reverbPusherBroadcasterHTTP API (Pusher-compatible)Yes
ablyAblyBroadcasterHTTP APIYes
redisRedisBroadcasterRedis Pub/SubNo
logLogBroadcasterPSR-3 LoggerNo
nullNullBroadcasterNo-opNo

Pusher and Ably drivers are wrapped in BroadcastPoolProxy instances to reuse HTTP connections across multiple broadcasts, configured via the pool array in the driver configuration.

Sources: src/broadcasting/src/BroadcastManager.php289-379 src/broadcasting/public/broadcasting.php1-99

Channel Types and Authentication

Broadcasting supports three channel types with different authentication requirements:

Public Channels

Public channels require no authentication. Any connected client can subscribe. Channel names do not have a prefix.

Private Channels

Private channels require authentication and are prefixed with private- (Pusher/Ably) or have no special prefix but require callback authorization (Redis). The server verifies the user can access the channel by calling the registered channel callback.

Presence Channels

Presence channels extend private channels by tracking which users are subscribed. They are prefixed with presence- and require returning user information from the channel callback, not just a boolean.

Channel authentication is handled through the /broadcasting/auth route registered by BroadcastManager::routes(). The route excludes CSRF middleware to support cross-domain requests from WebSocket clients.

Sources: src/broadcasting/src/BroadcastManager.php74-94 src/broadcasting/src/Broadcasters/Broadcaster.php72-113 src/broadcasting/src/BroadcastController.php1-32

Event Broadcasting Flow

Events implement the ShouldBroadcast or ShouldBroadcastNow interface to indicate they should be broadcast. The flow differs based on the interface:


Sources: src/broadcasting/src/BroadcastManager.php171-203 src/broadcasting/src/PendingBroadcast.php1-51

Anonymous Events

The system supports anonymous events through the fluent AnonymousEvent API, allowing broadcasts without defining event classes:


The AnonymousEvent class implements ShouldBroadcast and provides methods to configure the broadcast via method chaining. The send() method creates a PendingBroadcast which dispatches on destruction, while sendNow() forces synchronous broadcast.

Sources: src/broadcasting/src/AnonymousEvent.php1-154 src/broadcasting/src/BroadcastManager.php138-158

Configuration

Broadcasting configuration is stored in config/autoload/broadcasting.php with driver-specific settings:

Configuration KeyPurpose
broadcasting.defaultDefault driver name
broadcasting.connections.{driver}.driverDriver type (pusher, ably, redis, etc.)
broadcasting.connections.{driver}.keyAPI key for Pusher/Ably
broadcasting.connections.{driver}.secretAPI secret for Pusher/Ably
broadcasting.connections.{driver}.app_idApplication ID
broadcasting.connections.{driver}.optionsDriver-specific options
broadcasting.connections.{driver}.poolConnection pool configuration

Connection pool configuration applies to Pusher and Ably drivers and controls the size and lifetime of the connection pool maintained by BroadcastPoolProxy:


Sources: src/broadcasting/public/broadcasting.php1-99 src/broadcasting/src/BroadcastManager.php252-258

Integration with Queue System

Broadcasting integrates tightly with the queue system to enable asynchronous event delivery. When BroadcastManager::queue() is called:

  1. Event is cloned to avoid mutation issues
  2. Queue connection and queue name are determined from event properties
  3. A BroadcastEvent job wrapping the event is pushed to the queue
  4. Queue worker processes the job and calls Broadcaster::broadcast()

For unique broadcasts (events implementing ShouldBeUnique), the system wraps the event in UniqueBroadcastEvent and uses cache-based locking to prevent duplicate broadcasts:

Sources: src/broadcasting/src/BroadcastManager.php174-211 src/broadcasting/src/UniqueBroadcastEvent.php1-54

Socket ID and Broadcast Exclusion

The broadcasting system supports excluding the event originator from receiving the broadcast through socket IDs. The socket ID is extracted from the X-Socket-ID header in HTTP requests and stored in the event's $socket property.

When toOthers() is called on a PendingBroadcast or AnonymousEvent, it retrieves the current socket ID via BroadcastManager::socket() and attaches it to the event. Broadcasters then exclude this socket ID when publishing to the service.

The InteractsWithSockets trait provides convenience methods:

  • dontBroadcastToCurrentUser(): Sets socket to current request socket
  • broadcastToEveryone(): Clears socket to include all users

Sources: src/broadcasting/src/BroadcastManager.php126-134 src/broadcasting/src/InteractsWithSockets.php1-35 src/broadcasting/src/PendingBroadcast.php32-42

Channel Registration and Authentication Flow

Channel authentication callbacks are registered during application bootstrap and shared across all broadcaster instances through a static registry:


Sources: src/broadcasting/src/Broadcasters/Broadcaster.php36-85 tests/Broadcasting/BroadcasterTest.php385-401

Driver-Specific Features

Pusher/Ably Signature Authentication

Pusher and Ably broadcasters generate HMAC signatures for channel authentication following the Pusher protocol. The signature format differs for private vs presence channels:

  • Private channels: {public_token}:{hmac_sha256(socket_id:channel_name)}
  • Presence channels: Includes user data in signature and returns channel_data JSON

Sources: src/broadcasting/src/Broadcasters/AblyBroadcaster.php91-98

Redis Pub/Sub

The Redis broadcaster publishes events to Redis channels using the RedisFactory from Hyperf. Channel names are prefixed with the configured database prefix:

Sources: src/broadcasting/src/BroadcastManager.php355-363

Connection Pooling

Pusher and Ably drivers use connection pooling through BroadcastPoolProxy, which implements the PoolProxy pattern. The proxy maintains a pool of broadcaster instances and automatically handles connection reuse and release:

Sources: src/broadcasting/src/BroadcastPoolProxy.php1-44 src/broadcasting/src/BroadcastManager.php41-61

Channel Wildcards and Model Binding

Channel patterns support wildcards with implicit model binding similar to route model binding. When a channel is registered with parameters like channel-name.{id}, the broadcaster:

  1. Extracts parameter values from the channel name
  2. Matches parameter names to callback parameters
  3. Resolves model instances if parameter type-hints UrlRoutable
  4. Passes resolved models or raw values to the callback

This enables patterns like:


Sources: src/broadcasting/src/Broadcasters/Broadcaster.php119-206 tests/Broadcasting/BroadcasterTest.php52-75

Guard-Based User Retrieval

Channel options support specifying authentication guards for user retrieval, allowing different channels to authenticate users via different guards:


The broadcaster attempts guards in order, returning the first authenticated user. If no guards are specified, the default guard is used.

Sources: src/broadcasting/src/Broadcasters/Broadcaster.php242-278 tests/Broadcasting/BroadcasterTest.php221-262

Facade Access

The Broadcast facade provides convenient access to the BroadcastManager instance with full IDE support through comprehensive PHPDoc annotations covering all methods from both the manager and the underlying broadcaster:

Sources: src/support/src/Facades/Broadcast.php1-57