TWebTimers and Inactive Pages Workaround

I use a lot of TWebTimer components in my project and they work pretty well. However, I recently learned that timers do not get triggered on a web page when that page is not active. Not really the fault of TWebTimer apparently, as this is a browser-enforced limitation and is enforced consistently across all of the browsers I use regularly.

In my case though I wanted to use a timer to display an automatic logout countdown delay popup message. The problem was this wasn't firing until the page was active again, perhaps long after the automatic logout had occurred (JWT expired in my case). So not really ideal.

The workaround I've been using is a JS library called HackTimer which as its name implies hacks the Javascript timer mechanism so that it triggers even when the page is not active. Simply adding this to the begining of my project.html file is all that was needed - must come before things like JQuery to be effective.

    <!-- HackTimer -->
    <script src="https://cdn.jsdelivr.net/npm/hacktimer@latest/HackTimer.silent.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/hacktimer@latest/HackTimerWorker.min.js"></script>

It is a bit overkill in that I don't really need all of my timers to use this mechanism, but as most of them are very short-duration UI-type timers, this isn't a big problem in my case. And my very limited understanding was that this was kind of an all-or-nothing approach, but I could be wrong there.

Does anyone know of a better workaround? Been using this for awhile with no issues so I'm happy with the end result, but it is an external dependency (and an aging one at that) that may have a more current or more appropriate solution?

I have one main form and all the other forms are rendered in the "Content" div. I have timers that I need across the application on the main form, which is always active.

By "active" I mean that the user opens a different tab in Chrome or Firefox or whatever and is off doing something else entirely, with my app now "inactive". It is the browser itself that seems to suspend the Javascript timers, nothing to do with how timers in my app are arranged. When the tab is revisited, all the timers that had been paused by the browser are then triggerd.

Now I understand.

You'd think a browser would allow you to register a timer, in a similar way to how an OS does.

At least you have found a workaround.

In terms of the JWT, I am working on updating that with each major call back to the server (CRUD endpoints mainly) so that the user doesn't get logged out unless they are inactive.

Presumably browsers behave this way due to many poorly crafted websites that abuse timers. Probably saves some battery drain as well. In any event, the workaround works, just not sure what to do when the day comes and it doesn't work.

The JWT side of things is fine, not really a security issue. Like you, I periodically renew the user's JWT automatically if they're actually doing anything.

This timer was just to present a 2-minute countdown indicating they'd be logged out, kind of like what you see on banking sites. Problem was that it wouldn't display when the browser tab wasn't the active tab and so when it became the active tab it would start counting down from the 2-minute point even if it had been hours since it was last active. Now it just displayes the 2-minute countdown regardless of whether it is active or not - and you can tell from the tab's title whether it is logged in still or not.

Haven't looked in detail, but perhaps a service worker can come to help?

Perhaps? That's a level of coding beyond my understanding though. I know the service worker is there but I've never had to actually do anything with it - kind of just magic :grin:

What might be ideal would be to add a "Service Worker" True/False property to TWebTimer that defaults to False but if True provides an alternate implementation using a service worker?

Not trivial to dynamically create service worker code from a component property.
From a usage viewpoint it would indeed by very easy. It's something to be deeper researched.