Broadcasting


  • Our broadcast driver implementation (BroadcastBroker) will already be bound into the container by default.
  • This driver is responsible for extracting private/presence channel names and dispatching the broadcast event that any action in our system calls for.
    • If push notifications are enabled, this broker will also forward its data to our PushNotificationService. The service will then fire a PushNotificationEvent that you can attach a listener to handle your own FCM / other service.
  • ALL events we broadcast implement laravel's ShouldBroadcastNow interface, and will not be queued, but broadcasted immediately.

Default push notifications config:

'push_notifications' => env('MESSENGER_PUSH_NOTIFICATIONS_ENABLED', false),

Channel Routes

$broadcaster->channel('messenger.call.{call}.thread.{thread}', CallChannel::class); // Presence
$broadcaster->channel('messenger.thread.{thread}', ThreadChannel::class); // Presence
$broadcaster->channel('messenger.{alias}.{id}', ProviderChannel::class); // Private

View our API Explorer for a list of each broadcast and example payloads.


Private Channel

Events and their broadcastAs name

CallEndedBroadcast::class => 'call.ended',
CallIgnoredBroadcast::class => 'call.ignored',
CallJoinedBroadcast::class => 'joined.call',
CallLeftBroadcast::class => 'left.call',
CallStartedBroadcast::class => 'incoming.call',
DemotedAdminBroadcast::class => 'demoted.admin',
FriendApprovedBroadcast::class => 'friend.approved',
FriendCancelledBroadcast::class => 'friend.cancelled',
FriendDeniedBroadcast::class => 'friend.denied',
FriendRemovedBroadcast::class => 'friend.removed',
FriendRequestBroadcast::class => 'friend.request',
KickedFromCallBroadcast::class => 'call.kicked',
KnockBroadcast::class => 'knock.knock',
MessageArchivedBroadcast::class => 'message.archived',
NewMessageBroadcast::class => 'new.message',
NewThreadBroadcast::class => 'new.thread',
ParticipantPermissionsBroadcast::class => 'permissions.updated',
ParticipantReadBroadcast::class => 'thread.read',
PromotedAdminBroadcast::class => 'promoted.admin',
ReactionAddedBroadcast::class => 'reaction.added',
ReactionRemovedBroadcast::class => 'reaction.removed',
ThreadApprovalBroadcast::class => 'thread.approval',
ThreadArchivedBroadcast::class => 'thread.archived',
ThreadLeftBroadcast::class => 'thread.left',

Laravel Echo private channel example:

Echo.private('messenger.user.1')
  .listen('.new.message', incomingMessage)
  .listen('.thread.archived', threadLeft)
  .listen('.message.archived', messagePurged)
  .listen('.knock.knock', incomingKnok)
  .listen('.new.thread', newThread)
  .listen('.thread.approval', threadApproval)
  .listen('.thread.left', threadLeft)
  .listen('.incoming.call', incomingCall)
  .listen('.joined.call', callJoined)
  .listen('.ignored.call', callIgnored)
  .listen('.left.call', callLeft)
  .listen('.call.ended', callEnded)
  .listen('.friend.request', friendRequest)
  .listen('.friend.approved', friendApproved)
  .listen('.friend.cancelled', friendCancelled)
  .listen('.friend.removed', friendRemoved)
  .listen('.promoted.admin', promotedAdmin)
  .listen('.demoted.admin', demotedAdmin)
  .listen('.permissions.updated', permissionsUpdated)
  .listen('.friend.denied', friendDenied)
  .listen('.call.kicked', callKicked)
  .listen('.thread.read', threadRead)
  .listen('.reaction.added', reactionAdded)
  .listen('.reaction.removed', reactionRemoved)
  • Most data your client side will receive will be done through the user/providers private channel. Broadcast such as messages, calls, friend request, knocks, and more will be transmitted over the ProviderChannel. To subscribe to this channel, follow the below example using the alias of the provider you set in your providers settings:
    • private-messenger.user.1 | User model with ID of 1
    • private-messenger.company.1234-5678 | Company model with ID of 1234-5678

Thread Presence Channel

Events and their broadcastAs name

EmbedsRemovedBroadcast::class => 'embeds.removed',
MessageEditedBroadcast::class => 'message.edited',
ReactionAddedBroadcast::class => 'reaction.added',
ReactionRemovedBroadcast::class => 'reaction.removed',
ThreadAvatarBroadcast::class => 'thread.avatar',
ThreadSettingsBroadcast::class => 'thread.settings',

Laravel Echo presence channel example:

//Presence
Echo.join('messenger.thread.1234-5678')
  .listen('.thread.settings', groupSettingsState)
  .listen('.thread.avatar', groupAvatarState)
  .listen('.message.edited', renderUpdatedMessage)
  .listen('.reaction.added', reactionAdded)
  .listen('.reaction.removed', reactionRemoved)
  .listen('.embeds.removed', embedsRemoved)
  • While inside a thread, you will want to subscribe to the ThreadChannel presence channel. This is where realtime client to client events are broadcast. Typing, seen message, online status are all client to client and this is a great channel to utilize for this. The backend will broadcast a select few events over presence, such as when the groups settings are updated, or group avatar changed, or a user edited their message. This lets anyone currently in the thread know to update their UI! See example below for channel format to subscribe on:
    • presence-messenger.thread.1234-5678 | Thread presence channel for Thread model with ID of 1234-5678

Call Presence Channel

  • There are currently no broadcast from the backend to a call's presence channel. This channel exists for you to have a short-lived channel to connect to while in a call.
    • presence-messenger.call.4321.thread.1234-5678 | Call presence channel for Call model with ID of 1234 and Thread model with ID of 1234-5678

Laravel Echo presence channel example:

Echo.join('messenger.call.4321.thread.1234-5678').listen('.my.event', handleMyEvent)

Interacting with the broadcaster

  • It is very simple to reuse our included broadcast events, or to create your own, while being able to broadcast them yourself!
  • The BroadcastDriver will be bound in the container, so you can call to it anytime using our helper, or dependency injection.
use RTippin\Messenger\Contracts\BroadcastDriver;

//Using the container / dependency injection.
$broadcaster = app(BroadcastDriver::class);

//Using our helper.
$broadcaster = broadcaster();

Example broadcasting NewMessageBroadcast with custom data to a users private messenger channel

use RTippin\Messenger\Broadcasting\NewMessageBroadcast;

broadcaster()->to($receiver)->with([
    'body' => 'some data',
    'payload' => 'Any array data you want to send',
])->broadcast(NewMessageBroadcast::class);
Echo.private('messenger.user.1').listen('.new.message', incomingMessage)

Creating and broadcasting custom events

  • Your custom broadcast event will need to extend our abstract MessengerBroadcast class.
  • All you need to declare is the broadcastAs method. Everything else is set for you on demand!

Example custom broadcast event

<?php

namespace App\Broadcasting;

class CustomBroadcast extends MessengerBroadcast
{
    /**
     * The event's broadcast name.
     *
     * @return string
     */
    public function broadcastAs(): string
    {
        return 'custom.broadcast';
    }
}
use App\Broadcasting\CustomBroadcast;

broadcaster()->to($receiver)->with([
    'message' => 'This is easy!',
])->broadcast(CustomBroadcast::class);
Echo.private('messenger.user.1').listen('.custom.broadcast', handleCustom)

Setting up your custom BroadcastDriver

  • If you want to create your own broadcast driver implementation, your class must implement our BroadcastDriver interface.
  • Once created, register your custom driver implementation in your MessengerServiceProvider boot method
<?php

namespace App\Providers;

use App\Brokers\CustomBroadcastBroker;
use Illuminate\Support\ServiceProvider;
use RTippin\Messenger\Facades\Messenger;

class MessengerServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        Messenger::setBroadcastDriver(CustomBroadcastBroker::class);
    }
}