laravel / reverb

Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.
https://reverb.laravel.com
MIT License
1.02k stars 71 forks source link

Dispatch event when connection is terminated #150

Closed AmirRezaM75 closed 4 months ago

AmirRezaM75 commented 4 months ago

Hi, I couldn't find a way to detect when connection is closed on private channel. Either by closing the browser tab or using 'pusher.disconnect()'. The message is simply logged here:

https://github.com/laravel/reverb/blob/0b337bea0a1c471bc87ba2531ce63ba7da80705f/src/Protocols/Pusher/Server.php#L84

michaelnabil230 commented 4 months ago

Can see https://github.com/laravel/reverb/pull/91

AmirRezaM75 commented 4 months ago

@michaelnabil230 I see your PR. For ServerStarted and ServerStopped you can come up with your own custom command that starts the service. (it's the highest level component, so it's easy to override it). SubscribedToChannel, UnsubscribedFromChannel and NewConnection can be handled with existing MessageSent and MessageReceived.

But we have no way to find out if the connection is closed or not. (or at least I couldn't)

AmirRezaM75 commented 4 months ago

we want to keep events to a minimum to prevent users from unintentionally blocking the server. https://github.com/laravel/reverb/issues/91#issuecomment-2003360021

@joedixon I saw your Laracon presentation. For online status indicator joining and leaving in PresenceChannel will do the trick. But only for group chat when people are joining specific channel. Assume a simple chat app when you have 200 friends and wants to show who is online. How we can do this with Reverb?

michaelnabil230 commented 4 months ago

Ummmm 🤨 ‎‏Let's see what he will tell us @joedixon

But if the has event when close the socket why don't have event when socket is starting?

joedixon commented 4 months ago

Thanks @AmirRezaM75 for the pull request.

I don't want to add any more events right now as they expose the potential to block the event loop and increase memory and CPU usage.

I saw your Laracon presentation. For online status indicator joining and leaving in PresenceChannel will do the trick. But only for group chat when people are joining specific channel. Assume a simple chat app when you have 200 friends and wants to show who is online. How we can do this with Reverb?

Right now, you would have to use a PresenceChannel to achieve this.

AmirRezaM75 commented 4 months ago

@joedixon Assume we have user.{id} presence channel. Me (with id=1) and my friends can join user.1 channel. and yes we can manage who is online and offline with this approach. But it has three problems:

1) When user 1 enters chat app, we must iterate through their list of friends and join to appropriate channel. it's not a good method especially if the user has a large number of friends. Additionally, there's a possibility that the server returns only a paginated list of friends, not the entire list, and the client don't have any idea about remaining.

2) User 2 and 3 are friends with User 1, thus they will join the "user.1" channel. However, even if User 2 and 3 are not friends, they can still become aware of each other if they open the network tab, resulting in data leakage.

3) I guess before joining each of them we send a post request to /auth/broadcast

joedixon commented 4 months ago

Can you have a general channel. For instance, in my demo, I had a workspace channel which managed presence for everyone connected and then private channels where users need to be subscribed before they can join.

AmirRezaM75 commented 4 months ago

@joedixon Thanks for response.

Not sure is it a good idea to have one channel for handling presence for the entire app. because everyone can understand how many people are online in your website.

Also I found this in pusher documentation

Presence channels have some limits associated with them: 100 members maximum, 1KB limit for user object, and maximum 128 characters for user id

I don't know is it true for reverb or not!?

As I said the solution works for group, workspace etc. But for friend list (followers) like discord, telegram; doesn't work. because they are not part of one specific channel.

I understand your concerns about "blocking the event loop", but in my opinion we can't stop user from misusing the system. Anyone that goes deep like this, probably know about consequences.

Anyway the ball is in your court :) Thanks for this project. Learned a lot.