ably / laravel-broadcaster

Official Laravel Ably Broadcaster
https://laravel.com/docs/broadcasting
Apache License 2.0
44 stars 7 forks source link

Monitor channel connection/disconnect #47

Closed abeloha closed 4 weeks ago

abeloha commented 1 month ago

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

sacOO7 commented 1 month ago

Hi @abeloha thanks for raising the issue! I didn't quite get your problem. Can you clarify a bit more in detail

sacOO7 commented 1 month ago

Since this is a ride sharing app like uber I can give some architectural suggestions. Business model of ride sharing apps resolve around location of both rider and driver.

You should create a rest API, that returns list of nearby zip codes based on given user location. User can be both rider or driver. Once user logs in, he should request nearby zip codes by sending his location and join the room for each zip code

Echo.join(`room.${zipcode}`)
    .here((users) => {
        // here you get updated list of all present drivers and riders along with their location
    })
    .error((error) => {
        console.error(error);
    });

You should authorize users on presence channels by sending right metadata back as per https://laravel.com/docs/11.x/broadcasting#authorizing-presence-channels

use App\Models\User;
Broadcast::channel('room.{zipcode}', function (User $user, int $zipcode) {
    if($user->canJoinRoom($zipcode))
        {
           // location will contain both longitude, latitude, user type can either be driver or rider
            return ['id' => $user->id, 'name' => $user->name, 'location' => $user->location, 'userType' => $user->type];
        }
});

Also refer to https://github.com/ably-labs/laravel-broadcast-app for more information. Specifically channels.php

sacOO7 commented 1 month ago

@abeloha let me know if you have more questions, otherwise we can close the issue

abeloha commented 1 month ago

Thanks @sacOO7 for the architectural suggestions. When a ride request comes, I want to send only to channel that is active. If there is no user in channel 'room.{zipcode}', I want do not want to send to that channel.

The way I currently went around it is to periodically synchronize presence information directly from Ably using a scheduled task.

sacOO7 commented 1 month ago

I don't think you need a scheduled task for this. You should rather use list to store active channels for all zipcodes

var activeChannels = []
Echo.join(`room.${zipcode}`)
    .here((users) => {
        // here you get updated list of all present drivers and riders along with their location
        if (users.length == 0) {
           activeChannels.remove(`room.${zipcode}`)
        } else {
          activeChannels.append(`room.${zipcode}`)
        }
    })
    .error((error) => {
        console.error(error);
    });
sacOO7 commented 1 month ago

Let me know if you are facing any other issues. Otherwise we can close the issue

sacOO7 commented 4 weeks ago

Since, issue is not laravel-broadcaster specific, I will close the issue. If you need help in the future, please raise new issue.