Android & Webapp, call background refresh when mobile is locked - javascript

For an alert system following a reservation (private use), I would like my webapp to send a notification.
I want every X minutes an ajax call is made, checks if there is a new reservation and if so sends the notification.
I have no problem for the operation and the sending of the notification unless the mobile is locked.
I have seen several posts on this subject but they are dated.
I tried settimetout, setinterval and background-timer, without success.
Maybe today there is a way?
EDIT :
To be more clear. My webapp manages to send notifications even when the mobile is locked, but the verification interval seems random.
A test with a setInterval of 1 minute, sends me a notification after 2 minutes for example, then 5 minutes later... not always with the same interval.
EDIT 2 :
In response to Gowtham K K, I tried using a web worker for the setInterval but it doesn't work when mobile is locked.
Code in my main page :
if(window.Worker){
var myWorker = new Worker("sw2.js");
myWorker.postMessage(0);
myWorker.onmessage = function(e){
var dt = new Date();
var hm = dt.toISOString().substring(11, 19);
_test.innerHTML += hm+"<br>";
}
}
Code in sw2.js
self.onmessage = function(e) {
self.postMessage(0);
init();
}
function init() {
setInterval(send,60000);
}
function send() {
self.postMessage(0);
}

As far as I know, service worker would atleast might solve most of your problem.
Service worker is a background worker for a website. It is supported by most modern browsers.
It acts an proxy layer between browser and web server. For example when user laoded web app and then internet got disconnected. At that time you can register in service worker and so when user connects to internet again, you can make the service worker task to run even when the user is not seeing the webpage.
Here you can handle push notification inside service worker .
Service worker has its own lifecycle.
In your case you can try running the background timer inside the service worker and handle the push notification.
Some Useful links:
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
https://medium.com/#a7ul/beginners-guide-to-web-push-notifications-using-service-workers-cb3474a17679

Related

Run a persistent web worker in the background without getting throttled

I would like to run a web worker in the background (on mobile, it works on desktop) which does an action every minute by sending an HTTP request. Unfortunately, after having the website in the background for about 5 minutes, no HTTP request will be sent anymore... All network requests will resume once you go back to the website.
It seems like the web worker is not allowed to be run in the background, at least not on mobile, as it works fine on desktop. I could not find any source stating why it is throttled, and what can be done about it. I found a similar issue dating from 2017, which is 4 years ago and has not been answered quite the way I want it and might also be outdated.
I thought of the following solutions:
Normally in native Android you can show a notification which will ensure that your app keeps running in the background, I was wondering if this would also work on web in combination with web workers.
If you open a web socket in your web worker, will it keep your web worker alive in the background?
Progressive web app. Does not seem to keep it active unfortunately..
Is there anything I could do about this?
All modern browsers restrict background usage. It has a really simple reason: Background tasks require resources, and users dont want a million websites in the background to eat all your RAM. And malicious websites could just use the CPU from users for bitcoin mining etc.
But there is a way to do stuff in the background. You already mentioned it in the question: You need to send push notifications. You can just include a fetch() in your push notification handler.
But here's the catch: You have to send a notification every time you want your site to fetch something, or your requests will always/sometimes be blocked depending on your browser. From MDN:
Activating a service worker to deliver a push message can result in increased resource usage, particularly of the battery. Different browsers have different schemes for handling this, there is currently no standard mechanism. Firefox allows a limited number (quota) of push messages to be sent to an application, although Push messages that generate notifications are exempt from this limit. The limit is refreshed each time the site is visited. In comparison, Chrome applies no limit, but requires that every push message causes a notification to be displayed.
You just need to set up Push Notifications. There's a great guide from Google that you can follow if you don't know how to set up push notifications.
An implementation in a service worker would look like this:
self.addEventListener('push', function(event) {
if (!(self.Notification && self.Notification.permission === 'granted')) {
return;
}
// The HTTP request
fetch("...");
var data = {};
if (event.data) {
data = event.data.json();
}
var title = data.title || "Background activity";
var message = data.message || "You can ignore this";
var icon = "images/new-notification.png";
var notification = new Notification(title, {
body: message,
tag: 'simple-push-demo-notification',
icon: icon
});
notification.addEventListener('click', function() {
if (clients.openWindow) {
clients.openWindow('https://example.blog.com/2015/03/04/something-new.html');
}
});
});
(Code copied from MDN)

How do I call a function periodically in a manifest v3 Chrome extension?

Service workers replace background pages in manifest v3 chrome extensions, and I'm trying to use one for my extension. I need to be able to run a function periodically, and it looks like alarms are the way to go. In the example they recommend doing this in the top level of the service worker:
chrome.alarms.create({ delayInMinutes: 3.0 });
chrome.alarms.onAlarm.addListener(() => {
chrome.action.setIcon({
path: getRandomIconPath(),
});
});
From what I understand though, weather or not my service worker gets killed in between events is non-deterministic. I believe if the browser kills my service worker this will be called every 3 minutes, since when the script is re-started to handle the alarm, it will run the first line again and queue up another alarm.
By contrast, if the browser lets my service worker live for the 3 minutes in between alarms this won't loop, because it will only call addListener() once, but will call the callback twice (once for the first alarm that originally spawned this service worker, and again for the alarm registered on the first line of this invocation of the service worker). The service worker will then eventually die and no alarm will ever wake it again.
Am I misunderstanding how events work here? If not, how do I register a re-occurring alarm once chrome.alarms.create({ periodInMinutes: 3.0 }); and avoid re-registering it every time my service worker is re-started?
NOTE: delayInMinutes fires once, periodInMinutes is re-ocuring.
Although it's non-deterministic but the rules are quite simple and the worker behaves almost exactly like the old event page of ManifestV2, the major points are:
it wakes up when a registered API event occurs
it runs the entire script so the API listeners are re-registered
it runs the listener for the API event that woke it
it unloads after 30 seconds (15 in MV2) after the last API event; if another API event is triggered the unload timer is restarted in MV2 (but not in MV3); the timer will be extended by five minutes if there is an open port for chrome.runtime messaging, in MV3 the messaging ports are force-disconnected after five minutes whereas in MV2 these ports never force-disconnect and thus keep the MV2 event page alive.
Now back to that demo script. You're right: it relies on non-deterministic behavior. It's just bad like many examples in the documentation for extensions. Use API reference and devtools debugger.
A more realistic example would be to register an alarm just once, for example in chrome.runtime.onInstalled event, because the alarms are remembered by the browser internally. Also, it's best to give it an id so we can check for its existence:
chrome.runtime.onInstalled.addListener(() => {
chrome.alarms.get('periodic', a => {
if (!a) chrome.alarms.create('periodic', { periodInMinutes: 3.0 });
});
});
chrome.alarms.onAlarm.addListener(() => {
chrome.action.setIcon({
path: getRandomIconPath(),
});
});

How to notify without websocket

I want to integrate a simple notification system in my react application. I want to notify for example:
- new post (when the user post the system need time to transcode the media attached and the publication)
- missing settings (the user need to compile some information)
- interesting posts etc..
There is a simple way to add a websocket, like socket.io, to a reactjs app with an aws lambda backend?
All the notification not need to be read in real time, maybe an ajax call every 2 minutes can solve my problem, but, in this case, someone can help me avoid ajax call if the app isn't used(like if the app remain opened in a foreground tab...)
componentDidMount() {
this.liveUpdate()
setInterval(this.liveUpdate, 120000);
}
liveUpdate() {
axios.get(endpoint.posts+'/live/', cfg)
.then(res => {
// ...
});
}
This code is in the footer component, the call happen every 120 seconds, but the call will still happen also if a user leave the application opened in the browser and not use it, this on a lambda backend mean a waste of money.
There are 3 main ways of notifying that I can think of at the moment...
Long polling (using ajax etc)
Websocket
Push Notification
Push (though) requires permission from the user

Delay an HTML5 notification?

I've been looking at the state of HTML notifications and service workers, and was wondering - is it possible to show a notification on a delay? Basically, I would like to be able to say "remind me in 30 minutes" (or whatever), then push a notification to the user 30 minutes later. That could be scheduled immediately, but I'm not seeing any functionality that allows it.
Am I missing something or is it impossible in the current state of (particularly) Chrome APIs?
This is possible but not straightforward with service workers, at least in their present form. It's not straightforward because a service worker can't keep itself awake for half an hour or wake itself up with a setTimeout or setInterval. The browser will just shut the worker down and will keep no record of any timeouts or intervals. You could wake it up with a message from an open tab, but you said that you don't want to have to have to keep an open tab, and if you assume an open tab then why even bother with the service worker anyway? As Jeff Posnick suggested in a comment, you could perhaps eventually use the Sync or PeriodicSync APIs, but, as he also points out, they aren't implemented yet and aren't really intended for this anyway.
You can accomplish what you want in current versions of Chrome using the Push API, but you'll have to include the server in the loop and set yourself up with a push notification service (i.e. GCM). Here's how it would work, roughly:
When you decide to delay a notification, let the server know about it
After a delay, the server sends out a push message for your user
The service worker is woken up in response to the push and creates a new notification
This last part will be a hassle, because currently you can't actually send any kind of payload with a push, so your service worker will need some way of figuring out what the notification is supposed to be. Maybe the server has a list of snoozed notifications and the service worker can get it from there, or maybe you saved them in IndexedDB.
Adapted from https://developer.cdn.mozilla.net/media/uploads/demos/e/l/elfoxero/c17223c414d8ddafb7808972b5617d9e/html5-notifications_1400214081_demo_package/:
<script>
var Notification = window.Notification || window.mozNotification || window.webkitNotification;
function show() {
window.setTimeout(function () {
var instance = new Notification("Hello World!");
}, 5000);
return false;
}
</script>
Notify me!

SignalR & IE Issue - poll is pending

I have a Problem With IE and SignalR, I'm using the it to perform a Syncing action between two databases, the Actions Completed successfully on Google Chrome / Firefox / Safari in all scenarios.
Using IE for the First time the sync performed successfully but only for one time, in the second time a pending request stack and the page stay freeze for ever.
I found a solution online which is changing the transport mode.
But page still freezing.
if (isIE()) {
$.connection.hub.start({ transport: ['serverSentEvents','foreverFrame']}).done(function () {
progressNotifier.server.DoMyLongAction();
});
}else{
$.connection.hub.start({ transport: ['serverSentEvents','longPolling'] }).done(function () {
progressNotifier.server.DoMyLongAction();
});
}
I'm Using:
SgnalR v2.1.0.0
.Net framework v4.5
jquery v1.8
is it an Issue or I'm Doing something wrong ?
Edit
my application use Jquery progress bar and i Update this progress bar using this Code:
server side:
Clients.Caller.sendMessage(msg, 5, "Accounts");
client side:
progressNotifier.client.sendMessage = function (message, value, Entity) {
pbar1.progressbar("value", nvalue);
};
it's working on Firefox so I thought it's a signalR Issue !! Now i became confused if it's working as expected then what causes this problem ?
you can try use EventSource (SSE).
I am using this:
https://github.com/remy/polyfills/blob/master/EventSource.js
but modified, for SignalR:
http://a7.org/scripts/jquery/eventsource_edited.js
I am working with it for one year, SignalR just check for window.EventSource and it works.
The solution you found online is not likely to help your issue.
I doubt your IsIE() function is correctly identifying IE. If it was, SignalR should only be attempting to establish a "foreverFrame" connection, since IE does not even support "serverSentEvents". I would not expect IE to make any "/signalr/poll" requests, because those requests are only made by the "longPolling" transport.
Also, having a "pending" poll request in the IE F12 tool's network tab is entirely expected. This is how long polling is designed to work. Basically, as soon as a message is received the client makes a new ajax request (a long poll) to retrieve new messages. If no new messages are immediately available, the server will wait (for up to 110 seconds by default in the case of SignalR, not forever) for a new message to be sent to the client before responding to the pending long poll request with the new message.
Can you clarify exactly what issue you are having other than seeing a pending poll request showing up under the network tab? It would also help if you you enabled tracing in the JS client, provided the console output, and showed all the "/signalr/..." requests in the network tab.

Categories

Resources