Search code examples
phplaravelpusherlaravel-echopusher-js

Close support chat after connection timeout with Laravel Echo


I'm building a support chat application. It's built on Laravel Echo through Pusher.js.

There are two sides - support/admin and client. When a client starts a chat, support can accept it and they can chat together. It's working like it should be, but there is one thing. When the client goes offline (close browser, leave site, lost internet connection...) it should wait for about a few seconds (to make sure it was not a mistake) and then close the chat. So when he comes back in about an hour, there would not be any active chat.

I'm checking both sides' online status with presence channel with simple code:

this.presence = Echo.join('chat');

this.presence
    .listen('.pusher:subscription_error', (result) => {
        if(this.debug) {
            console.log(result);
        }
    })
    .listen('.pusher:member_added', (result) => {
        if(!!result.info.is_admin) {
            this.presence_users.push(result.info);
        }
    })
    .listen('.pusher:member_removed', (result) => {
        let found = _.find(this.presence_users, ['id', result.id]);
        let index = this.presence_users.indexOf(found);

        this.presence_users.splice(index, 1);
    })
    .here((result) => {
        this.presence_users = _.filter(result, ['is_admin', true]);
    });

On the support side it's a little different, but still the same logic (also don't worry - user's id is not id from database, but unique md5 identifier).

Presence channel is working good. But I can't find anywhere on the internet, how to set up connection_timeout URL? I just think it could be URL, where Pusher.js will post some data when the user goes offline, or connection is lost - my custom id field, for example. As I noted in the start, it should have some "cooldown", when user goes offline by mistake. This would help to close the chat when the user is not available to respond.

Do you have any experience with a similar problem? If so, how did you solve it? Or - is it even possible to solve it with Pusher.js?


Solution

  • Well, 7 days are gone and no answer here, so I think it's not possible the way I describe. But there can be a "hacky" way:

    1. Create a CRON job which runs every 10 minutes

    2. Script will get all chats from database with flag active or pending

    3. When chat has no recent messages (nothing from last 5-10 minutes), then check if users are online

    4. Get users from presence channel

    $response = $pusher->get('/channels/chat/users');
    if($response['status'] == 200) {
        $users = json_decode($response['body'], true)['users'];
    }
    
    1. If there is at least one of them online, skip, otherwise wait for a short time (5 seconds, just to be sure), check online status again and when they are still offline, close the chat.

    Haven't tested it, since it is not required yet. Maybe someone will find this helpful.