Does service worker runs on background even if browser is closed? - javascript

I see push notification for Facebook web in chrome only when I open chrome. I know that this notification are sent through service worker. I am wondering whether this background sync goes on even though browser is closed or only on opening chrome only these service-worker sync process get started and start sending push notification.

First thing to say is this depends somewhat on the platform. My understanding of chrome is:
On desktop platforms like windows and Mac OS X the browser needs to have some background process running for a service worker to be able to run. On Mac OS X this is quite easy to detect as the browser can have no windows open but the browser still has the glowing dot beneath it.
On mobile platforms it's easier to listen for events and handle them in an efficient manner, so in these cases the platform can wake up the browser which will then handle any corresponding events.
The above applies to any service worker api's.
On Desktop: If the browser is completely closed then service workers can not run and will not dispatch any events (i.e. no push or background sync events)
On Mobile: The events will still be dispatched (i.e. background sync will trigger when the users device comes online and push will be received and cause a push event).

I don't think service worker will be able to run if browser is closed. Because service-worker is able to send push notification only after I open the browser. If it is running in the background then it could have send notification even after closing browser also.

Little offtopic but it is possible to write Chrome extension where background script can run if Chrome is allowed to run in the background (configurable in settings). It can also use GCM.

In the context of receiving push messages on desktop, you will receive
messages when the browser is running, i.e. has the marking underneath
the icon.
This means the browser can have no windows open, and you'll still
receive the push message in your service worker, because the browser
in running in the background.
The only time a push won't be received is when the browser is
completely closed, i.e. not running at all (no marking). The same
applies for Windows, although it's a little trickier to determine
whether or not Chrome is running in the background.
source https://web.dev/push-notifications-faq/#why-doesn't-push-work-when-the-browser-is-closed

Related

Why doesn't Firefox wait for WebSocket connection?

I'm writing an application that first tries to open a WebSocket connection (to make sure no others are open; address collision checking) before firing off a custom protocol that will launch a one-time WebSocket server with the address that the browser tells it. All communication is done over localhost and some arbitrary port number, say 3000. I'm not doing anything special, just attempting to open a WebSocket:
var socket = new WebSocket("ws://localhost:3000/MyApp/");
socket.onclose = function(e) { console.error(e); }
When testing in Chrome, the WebSocket will actually stay in the CONNECTING state for a little bit, which is ideal, since it gives us some time to actually launch the app through the custom protocol. But in Firefox, the WebSocket immediately closes with code 1006 and I can't figure out why.
I've tried changing the about:config network.websocket.timeout.open setting to be 1000 (from 20), but that doesn't help. I've also found this related post: Websockets - chrome and firefox differences?. That hasn't lead me to finding an answer, either.
What am I missing?
Update 11/16/21
I'm using the Dev Tools in Chrome and FF to check out the requests. The weird thing is that Chrome is actually sending a request header as you'd expect, but in FF, the request is completely empty (0 Bytes). Maybe this is a problem with FF not supporting debugging native WebSockets (no wrapper libraries in use)? Is there some FF setting that nixes the request? But even more confusing is that the browser would hit the close event without ever hitting the open event.
Update 11/17/21
I realize that maybe this has something to do with launching a Custom Protocol Handler? I noticed that it will wait a second to try and connect to a web server if no CPH is launched, but then when I do launch a CPH, that is when it immediately closes the WebSocket. The CPH is launched via a link targeting "_parent".
It looks like the custom protocol is causing FF to stop trying to connect early. I created an anchor element, <a>, in the JS code and called "click()" on it after constructing it. No matter what target I gave it (e.g. _self), it would cause the connection attempt to stop.
So long story short, initiating a link, whether it be a a.click, window.open, or location.replace, will cause Firefox to nix any currently polling WebSockets!
The workaround is to just use an iframe to launch the custom protocol.

How to debug WebSocket / Server Sent Events reconnections on desktop?

I am developing an app that uses Server Sent Events (SSE - basically one-way websockets). If the user uses the site on their mobile chrome browser and then tabs out for about a minute, the SSE connection breaks. If the user then tabs back into the site, it doesn't refresh the page (this is good). But I still need to re-establish the SSE connection so that the server can resume sending messages to them without a refresh.
I'm trying to debug my implementation but having to do it on mobile is very tedious. I have to grab my phone, refresh the page, then tab out, wait 1 minute (so the connection can break), and then tab back in to determine if my code for re-establishing the connection worked properly.
I would much rather be able to debug this on desktop, but I haven't found a way. I have tried the following:
Tried 5 different Chrome extensions for sleeping a tab. Unfortunately, when you navigate back into the tab it just refreshes the page rather than resumes it.
Tried using USB Debugging, but the desktop keeps the tab open at all times even if you tab out on mobile, so the tab never sleeps.
Tried running debugger; in the Chrome Developer Tools console, but even if I let the Javascript sit with its execution frozen for 5+ minutes, it never breaks the SSE connection, so I can't test if reconnecting works.
Tried using an extension to kill the internet for Chrome, but miraculously, this still maintains the active websocket/SSE connections. Apparently Google engineers have deprioritized this effort?
Basically, I am looking to simulate the behavior that happens on mobile when you tab out of your web browser, wait a minute, and then tab back in (the Javascript execution is frozen, the SSE connection is broken after a minute or so, and then tabbing back in resumes Javascript and attempts to reconnect the SSE connection).
Is this possible?
I think that best change you have by emulating your android device. You can do so by installing android studio from https://developer.android.com/studio and then here you have all you need to start and manage your virtual android env https://developer.android.com/studio/run/managing-avds
This it the way I debug my whole mobile development
The most obvious solution to me would be to attach a listener that tracks the events related to tab activation and build some custom solution upon that.
Simply:
window.onfocus = () => {
// Restore SSE session
};
window.onblur = function () {
// Inactive
};
Just for info, SSE is a different protocol from websockets.
In case you are interested in using websockets implementation, I suggest the following library which works very well in my experience: https://www.npmjs.com/package/#stomp/stompjs
Stomp is an abstraction over the websocket protocol, but it also means you would need to implement this on the server side as well.
You can use the chrome://discards to freeze your tab.
You should close and restore the connection based on the Page LifeCycle events.
You Can Try to use pause execution
goto:
Chrome javascript console (Ctrl+Shift+J) > sources > pause script (press f8)
This simulates like a mobile tab switching so you can debug easily
I think this is the simple and easy solution. thanks

Why would a native messaging host for a chrome extension with a UI hang?

I have a native messaging host for a chrome extension that reads from the keychain in OS X (using Apple's keychain service). I make the call to chrome.runtime.sendNativeMessage when the browser action page is opened. When the keychain is already unlocked, the native program runs fine and returns a response on standard out. The problem occurs when the keychain is locked so OS X prompts the user to unlock the keychain with a UI alert (similar to this). The problem is that the native program hangs when it is called and the prompt doesn't appear immediately. The prompt only appears once I close the browser action popup, and it only appears briefly (less than a second). I know that the native application is running while waiting for the UI prompt since I added logs for when it starts and exits (I also check ps).
Does anyone know why the native application might be hanging? I thought that maybe the UI window was causing things to be blocked, so I tried forking a new thread in the native application to open the keychain. Unfortunately, that didn't work either.
When I run the program directly from the command line, I don't run into any of these issues and the prompt to unlock the keychain appears immediately.
Ps. I've tried chrome.runtime.connectNative too and that doesn't work either.
It turns out that the function I was using to read from standard in was waiting for an EOF so under certain circumstances, the native application was just suspended indefinitely.

Keep WebSocket alive in Mobile Safari

Is it possible to keep a html 5 web pages WebSocket connection open in Mobile-Safari once the screen is locked?
I want to send my users continuous updates throughout the day and it seems silly that their screens should always have to be unlocked to receive those notifications.
Are there any other options?
I don't think it's possible to keep the connection open while the browser is in the background, or when the screen is locked, the reason being that the app is essentially frozen in memory. Here's a quote from a similar question:
the reason you cant keep a network socket open, is that without your app jumping to the foreground when it receives a connection, it cannot respond to network traffic(because if it is not in the foreground its memory content is frozen).
However, I did find this page on Push Notifications for Websites that shows you 'how to sign up your users to receive notifications even when your site is not running in Safari'.
There are some other options: if you want to send continuous updates, you could write an app and either follow the instructions on Apple's site to keep a socket open permanently, or you could configure the app to implement Push Notifications.
I'm sorry I couldn't find a quick fix, but I hope at least one of these options works for you!
I have found a hacky way to keep WebSocket alive in Mobile Safari.
Basically it's the same solution as for this question.
Create an infinity looping audio file to keep Javascript running:
<audio loop src="http://www.sousound.com/music/healing/healing_01.mp3"></audio>
Note: some user interaction is required to initiate the audio file.
It would be nice if a WebSocket kept the browser alive in the same manner as an audio or video file.
PS this also works on Android.

Catch Apple Remote events in webbrowser with JavaScript

Is there a chance to use the Apple Remote with my web browser (Safari, Chrome or Firefox)? For example, my HTML page makes a transition if I click the right or left arrow. I want to cause this transition not only by pressing a key but also by clicking on my Apple Remote (which is usually used with Frontrow).
The condensed question is: do I have the chance to catch Apple Remote events with JavaScript?
theres a few ways of doing that, one eould be to use max msp or pure data as a socket client to http://socket.io then capture the apple remote on max or pd and send the events to the socket server. another way would be finding a plugin for the browser that is able to interface between the controller and the javascript running in the current tab.

Categories