Giter Site home page Giter Site logo

ably / laravel-broadcaster Goto Github PK

View Code? Open in Web Editor NEW
44.0 17.0 7.0 98 KB

Official Laravel Ably Broadcaster

Home Page: https://laravel.com/docs/broadcasting

License: Apache License 2.0

PHP 100.00%
ably broadcasting events laravel php realtime sdk livewire

laravel-broadcaster's Introduction

Ably Broadcaster for Laravel

Latest Stable Version Total Downloads License

Ably is the platform that powers synchronized digital experiences in realtime. Whether attending an event in a virtual venue, receiving realtime financial information, or monitoring live car performance data – consumers simply expect realtime digital experiences as standard. Ably provides a suite of APIs to build, extend, and deliver powerful digital experiences in realtime for more than 250 million devices across 80 countries each month. Organizations like Bloomberg, HubSpot, Verizon, and Hopin depend on Ably’s platform to offload the growing complexity of business-critical realtime data synchronization at global scale. For more information, see the Ably documentation.

This implements ably broadcaster as a independent service provider library for Laravel using ably-php. This library works with the ably-js based ably-laravel-echo client framework with enhanced features. This project is the successor to the pusher-client based ably broadcaster.

Features

  • Native ably-js support.
  • Low latency for client-events.
  • Update channel permissions for each user.
  • Update token expiry.
  • Disable public channels.
  • Fully compatible with pusher/pusher-compatible broadcasters, see migrating section.

Bug Fixes

Requirements

  1. PHP version >= 7.2.0
  2. Laravel version >= 6.0.0

Installation

You can install the package via composer

composer require ably/laravel-broadcaster

Setup

  1. Update .env file, set BROADCAST_DRIVER as ably and specify ABLY_KEY.
BROADCAST_DRIVER=ably
ABLY_KEY=ROOT_API_KEY_COPIED_FROM_ABLY_WEB_DASHBOARD

Warning - Do not expose ABLY_KEY to client code.

  1. Uncomment BroadcastServiceProvider in config/app.php
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
  1. If running Laravel 8 or older, edit config/broadcasting.php, add ably section to the connections array
        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY')
        ],

Finally, you are ready to install and configure Ably Laravel Echo, which will receive the broadcast events on the client-side.

Using Laravel Echo on client-side

Ably Laravel Echo is a JavaScript library that makes it painless to subscribe to channels and listen for events broadcast by your server-side broadcasting driver. Ably is maintaining a fork of the official laravel-echo module which allows you to use the official ably-js SDK. In this example, we will also install the official ably package:

npm install @ably/laravel-echo [email protected]

Once Echo is installed, you are ready to create a fresh Echo instance in your applications JavaScript. A great place to do this is at the bottom of the resources/js/bootstrap.js file that is included with the Laravel framework. By default, an example Echo configuration is already included in this file; however, the default configuration in the bootstrap.js file is intended for Pusher. You may copy the configuration below to transition your configuration to Ably.

import Echo from '@ably/laravel-echo';
import * as Ably from 'ably';

window.Ably = Ably;
window.Echo = new Echo({
    broadcaster: 'ably',
});

window.Echo.connector.ably.connection.on(stateChange => {
    if (stateChange.current === 'connected') {
        console.log('connected to ably server');
    }
});

Please take a look at the Ably Laravel Echo Docs for more information related to configuring ably-specific client options and implementing additional features.

Once you have uncommented and adjusted the Echo configuration according to your needs, you may compile your application's assets:

npm run dev

Configure advanced features

1. Modify private/presence channel capability. Default: Full capability

  • Channel access control rights are granted for each individual user separately using ably-capability. It defines list of access claims as per Channel Capabilities.
  // file - routes/channels.php
  // User authentication is allowed for private/presence channel returning truthy values and denied for falsy values.
  
  // for private channel
  Broadcast::channel('channel1', function ($user) {
      return ['ably-capability' => ["subscribe", "history"]];
  });
  
  // for presence channel
  Broadcast::channel('channel2', function ($user) {
      return ['id' => $user->id, 'name' => $user->name, 'ably-capability' => ["subscribe", "presence"]];
  });

2. Disable public channels. Default: false

  • Set ABLY_DISABLE_PUBLIC_CHANNELS as true in .env file.
    ABLY_DISABLE_PUBLIC_CHANNELS=true
  • Update ably section under config/broadcasting.php with
        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY'),
            'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false)
        ],

3. Update token expiry. Default: 3600 seconds (1 hr)

  • Set ABLY_TOKEN_EXPIRY in .env file.
    ABLY_TOKEN_EXPIRY=21600
  • Update ably section under config/broadcasting.php with
        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY'),
            'token_expiry' => env('ABLY_TOKEN_EXPIRY', 3600)
        ],

4. Use internet time for issued token expiry. Default: false

  • If this option is enabled, internet time in UTC format is fetched from the Ably service and cached every 6 hrs.
  • This option is useful when using laravel-broadcaster on a server where, for some reason, the server clock cannot be kept synchronized through normal means.
  • Set ABLY_SYNC_SERVER_TIME as true in .env file.
    ABLY_SYNC_SERVER_TIME=true
  • Update ably section under config/broadcasting.php with
        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY'),
            'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false)
        ],

Migrating from pusher/pusher-compatible broadcasters

The Ably Laravel broadcaster is designed to be compatible with all Laravel broadcasting providers, such as Pusher, Ably with the Pusher adapter, and all Pusher compatible open source broadcasters. Follow the below steps to migrate from other broadcasters.

1. Leaving a channel

To leave channel on the client side, use Ably Channel Namespaces conventions, instead of Pusher Channel Conventions.

 // public channel
Echo.channel('channel1'); // subscribe to a public channel
// use this 
Echo.leaveChannel("public:channel1"); // ably convention for leaving public channel
// instead of 
Echo.leaveChannel("channel1"); // pusher convention for leaving public channel

// private channel
Echo.private('channel2'); // subscribe to a private channel
// use this 
Echo.leaveChannel("private:channel2"); // ably convention for leaving private channel
// instead of 
Echo.leaveChannel("private-channel2"); // pusher convention for leaving private channel

// presence channel
Echo.join('channel3');  // subscribe to a presence channel
// use this
Echo.leaveChannel("presence:channel3"); // ably convention for leaving presence channel
// instead of 
Echo.leaveChannel("presence-channel3"); // pusher convention for leaving presence channel

2. Error handling

    channel.error(error => {
        if (error && error.code === 40142) { // ably token expired
            console.error(error);
            // take corrective action on UI
        }
    })

Note :

  • In the Echo.join().here(members => {}) implementation, members are updated every time a client joins, updates or leaves the channel, whereas when using Pusher this is only called once for first client entering the channel.
  • Ably behaviour follows the standard Echo PresenceChannel Interface here Method.

Addtional Documentation

  • Current README covers basic ably broadcaster+echo configuration for setting up laravel app and getting it running.
  • Please take a look at Laravel Broadcasting Doc for more information on broadcasting and receiving events.

Example

Public room example


Testing

  • To run tests use
composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Ensure you have added suitable tests and the test suite is passing (run vendor/bin/phpunit)
  5. Push to the branch (git push origin my-new-feature)
  6. Create a new Pull Request

Release Process

This library uses semantic versioning. For each release, the following needs to be done:

  1. Create a new branch for the release, named like release/1.2.4 (where 1.2.4 is what you're releasing, being the new version).
  2. Update the lib version in src/AblyBroadcaster.php.
  3. Run github_changelog_generator to automate the update of the CHANGELOG.md. This may require some manual intervention, both in terms of how the command is run and how the change log file is modified. Your mileage may vary:
  • The command you will need to run will look something like this: github_changelog_generator -u ably -p laravel-broadcaster --since-tag v1.2.4 --output delta.md --token $GITHUB_TOKEN_WITH_REPO_ACCESS. Generate token here.
  • Using the command above, --output delta.md writes changes made after --since-tag to a new file.
  • The contents of that new file (delta.md) then need to be manually inserted at the top of the CHANGELOG.md, changing the "Unreleased" heading and linking with the current version numbers.
  • Also ensure that the "Full Changelog" link points to the new version tag instead of the HEAD.
  1. Commit generated CHANGELOG.md file.
  2. Make a PR against main.
  3. Once the PR is approved, merge it into main.
  4. Add a tag and push it to origin - e.g.: git tag v1.2.4 && git push origin v1.2.4.
  5. Visit https://github.com/ably/laravel-broadcaster/tags and add release notes for the release including links to the changelog entry.
  6. Visit https://packagist.org/packages/ably/laravel-broadcaster, log in to Packagist, and click the "Update" button.

laravel-broadcaster's People

Contributors

andytwf avatar koossaayy avatar kwhohasamullet avatar owenpearson avatar qsdstefan avatar quintinwillison avatar sacoo7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-broadcaster's Issues

Allow sending message data as a string, not just as an array

We want to be able to send data as a string

Since we are using laravel's event facade, we are limited to the payload being an array. Looking at the getPayloadFromEvent function, it's clear that broadcastWith() must return an array, because it's calling array_merge on the payload.

Our use case

The reason we would like to send data as a string, which the ably-php library supports, is because we want to send a json-encoded string without it being bloated by double encoding.

This all started because we had some messages that were over the 64k limit. When I reached out to Ably support, it was suggested that we chunk the data, send it as multiple messages, and then put it together on the client side. That worked great until I realized that each chunk of serialized data was around 10k bigger after being serialized again as a part of the payload (which included a UUID to group the chunks, the total number of chunks, and the current chunk index).

So the idea I had was to reserve a fixed number of characters at the beginning for the metadata and then just send the whole thing as a concatenated string. Then I realized the limitation of laravel events and that became a dead end.

Our current solution

I have a solution that involves taking each chunk, calling json_encode on it to determine how many bytes over my max chunk size it becomes, and then reducing the chunk by that amount. It works, and is fast, but it's a shame that we have to sacrifice that message size for the double encoding.

Any ideas? Could we extend laravel to support sending strings? Or just bypass the laravel event facade? That would also be a shame because our unit tests use Event::assertDispatched.

┆Issue is synchronized with this Jira Task by Unito

Laravel 10 compatibility

Installing will result this error using Laravel 10

composer require ably/laravel-broadcaster
Info from https://repo.packagist.org: #StandWithUkraine
Using version ^1.0 for ably/laravel-broadcaster
./composer.json has been updated
Running composer update ably/laravel-broadcaster
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires ably/laravel-broadcaster ^1.0 -> satisfiable by ably/laravel-broadcaster[v1.0.0, v1.0.1, v1.0.2].
    - ably/laravel-broadcaster[v1.0.0, ..., v1.0.2] require illuminate/support ^6.0 || ^7.0 || ^8.0 || ^9.0 -> found illuminate/support[v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27, v9.0.0, ..., v9.52.0] but these were not loaded, likely because it conflicts with another require.

You can also try re-running composer require with an explicit version constraint, e.g. "composer require ably/laravel-broadcaster:*" to figure out if any version is installable, or "composer require ably/laravel-broadcaster:^2.1" if you know which you need.

Issue with client ID when using SPA like inertia

Posting something someone already posted on stackoverflow, anyone with same issue?


I'm using ably for broadcasting notifications in my admin panel, I've followed this repo https://github.com/ably/laravel-broadcaster, to setup ably/laravel-broadcaster and ably larvel echo for the client side I did ably laravel echo configuration in bootstrap.js as mentioned exactly in the repo

import Echo from '@ably/laravel-echo';
import * as Ably from 'ably';

window.Ably = Ably;
window.Echo = new Echo({
broadcaster: 'ably',
disconnectedRetryTimeout: 500
});
window.Echo.connector.ably.connection.on(stateChange => {
console.log(stateChange.current);
// if (stateChange.current === 'connected') {
// console.log('connected to ably server');
// }
});
everything works fine and notification is being broadcasted and received, but after the user login in my app laravel echo connection failes cuz of a clientId mismatch

Ably: Connection state: failed; reason: [ErrorInfo2: Mismatched clientId for existing connection; statusCode=401; code=40102; see https://help.ably.io/error/40102 ]
if I refreshed the page everything works fine again, it looks like after the client login, ably isn't updating the client id

Note 1: it worth mentioning that I'm using laravel inertia with vue to build my SPA applications

can anyone help? actually I don't know where to start


I am not sure if we can force the client_id to ably as usually the laravel broadcasting auth takes care of this

┆Issue is synchronized with this Jira Task by Unito

Optimize request-response time

  • For every client network request, Laravel makes a network request to Ably for getting server time.
  • This increases response time by almost 200ms, total response time ~ 350ms.
  • This is due to a lack of laravel support to persist static variables across multiple requests.
  • This needs to be optimized either via shared storage or shared memory.

Consider adding `queryTime` option

Currently we use Ably server time for token signing (core Ably SDKs don't do this by default). I think we should change the default behaviour and have it enabled via config since getting Ably time will slow down the initial token signing.

Modify keyName for `capability`

  • Possibly replace with rarely used reserved keyword, since capability is a commonly used property for a user.
    e.g. channel-capability, channel-permissions, channel-authz, channel-access etc

Monitor channel connection/disconnect

I have a ride sharing application where users join private channel and the app push data such as ride requests for drivers or driver response to riders.

The frontend connects to channel "user.{ID}" where the ID is the user id. E.g user 1 would connect to user.1, while user 300 would connect to user.300.

The set up works fine. Now, I want the application to monitor active connections such that no rider requests goes to drivers who are not active.

Any suggestions on how this can be accomplished?

┆Issue is synchronized with this Jira Task by Unito

Update migration doc

  • Update migration doc for handling ably specific descriptive errors.
  • Debug here method call on presenceChannel. Currently standard is implemented to detect every member change. Need to check how it works with pusher-client and pusher-broadcaster pointing to pusher-server via pusher-specific-keys

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.