I want to detect if the user closes the browser tab that my application is running in. If this happens, I want to shut down a connected physical device. I'd like the sequence of events to be: user closes the browser tab (or browser), callback function is triggered, callback function closes device.
I'm using the Bokeh Server to serve an application. I don't use CustomJS at all.
Ideally, I'm looking for some kind of callback function (something like on_browser_close). I can't find anything in document or session that might do.
Is there a way of detecting that the browser (tab) has been closed?
I think you want to make use of on_session_destroyed, which is described in Lifecycle Callbacks. In a "Directory Format" Bokeh application, add a module server_lifecyle.py:
# server_lifecyle.py
def on_session_destroyed(session_context):
# called when a session is closed (e.g. tab closed or time out)
Related
I have a process that adds tabs to Vivaldi (or any browser): one to an external url and one to a local html file. I am able to identify the process IDs associated with each tab.
I want to be able to close the tabs. I have tried kill <id>. That clears the page of the local file, but the tab is still there and can be reloaded if I refresh the page. kill has no effect on the tab associated with the external url.
Is there a way to do this?
Killing processes is the wrong approach here anyway because apart from causing unexpected termination and not orderly closing, nothing guarantees each tab to live its own process. You may have both of them living in the same process, or sharing a process with other, unrelated tabs. Bottom line, it's not going to work or at least it'll work only sometimes and cause collateral damage. (Others asked for such a way before.)
My suggestion would be a browser extension that uses native messaging. You could then ask it via the native messaging function to close certain tabs for you, using the officially supported tabs API that the browser exposes to extensions.
(These links are to the Chrome extension docs, but Vivaldi is Chromium-based as well and supports the same APIs.)
Alternative idea that works without an extension:
Tabs opened through the command line behave as if they were opened by a script of the same origin, insofar that the website in them is able to call window.close(). So depending on your use case, maybe you can arrange for the website in the tab to close the tab by itself.
If one of them is "external" in such a way that you can't control its contents, then you could instead have one tab open the other one through JavaScript, because then the first tab can close the second tab using close as well.
If you need a way to communicate to the website running in your tab(s) that you want it to close itself, you could also do something like starting a local server at a random unused port and passing the port into the website via a URL parameter1, and stopping the server when you want to close the tab. Then, inside your website you would regularly poll the local server URL using AJAX and close the tab when it fails2. (Remember to return CORS headers for this to work.)
This is just one of several possible ways, and yes it is a bit "hacky" - so I'm open to suggestions on how to improve on this idea.
Another alternative (which may or may not fit to your use case): Instead of opening a tab, you could open a separate popup window for each website using --app in the command line before the URL. Then you could find the corresponding window by checking what is the newest window with a matching title, and you could close it programmatically (check out xdotool and xwininfo).
1: Why not a fixed port number? Because you can't control whether something else is already listening on that port on the user's machine.
2: Why not the other way round, starting the server in order to close the tab? Because then you would have to wait to ensure that the website noticed that you started the server, and if you would stop the server too early then the tab would never close, so it's extra effort and an extra possible failure point, for example if there is high CPU usage at the moment or Vivaldi put the tab into sleep mode in the background. Additionally, with my method, killing your "manager" process would then also cause the tab to close instead of leaving it sticking around. And, finally, you don't want another process to interfere with your communication by opening a server on the same port that you chose before you do so, so it'll be best to open the server right away and not only once you want the tab to close.
I am working on an Electron app where I'd don't control the contents of the render process. For this portion of the app, I'm just browsing a remote URL outside of the app.
I'd like to be able to stream the console from that render process to the main process and detect the presence of certain messages and act upon them in the main process.
Since I don't control the render process I can't use IPC to send messages. If I launch Electron with the ELECTRON_ENABLE_LOGGING environment variable, I can stream the render process, but only to the terminal. I don't know how to access that data in the main electron process. Is this possible somehow?
Best shot would be using console-message event in webContents. (https://electronjs.org/docs/api/web-contents#event-console-message)
It allows to hook console messages from certain webcontents' console, but mind there is one known issue of param for those consoles are not forwareded: i.e console.log('message', ...args); you'll likely not able to grab args.
Is it possible to detect in Flex application browser window close event so that an action can be
started when user closes Flex application, does anyone know how to do that if it's possible in the
first place? The reason why i am asking this is because i have a multiuser Flex application where
every user has it's own directory on a server side. Application has logout button which triggers
cleanup of user's directory but what if the user just closes the window? I would like to be able
to lunch that same cleanup upon browser close window
In the page hosting your app, write a Javascript function triggered by window.onbeforeunload, and this function can call a function inside your Flex application.
Note that the onbeforeunload function is not guaranteed to work for all browsers.
I would not recommend that approach because the closing action fails too often, meaning worthless. My browser freezes and force-quitted several times a day. My computer sometimes freezes. My internet connection sometimes dies. I think, some browsers even do not guarantee those kinds of actions executed every time.
So, the session timeout might be one safe way in most cases.
You can also try having a socket connection, so that your server can ping if a user is alive and also can detect if socket is closed. Even socket, however, can be unresponsive or can be disconnected sometimes while user is still using the application.
You might want to be strategic.
How to clear the shared objects when user closes the browser abruptly?If the user opens the same application in two tabs, and user tries to close any one of the tab, we have to listen only the closed tab event.
Is there any ways..
It's a bit unclear what you're asking.
If you want to clear something every time the user closes the browser; then why would you want to store that value as a shared object? The purpose of a Shared Object is to persist between sessions, or uses, of the application.
If you're using Shared Object as a generic term to mean some "Stored State" in the flex app; then it will go away at the same time the browser is closed.
If you're using shared object as a generic term to mean some a server side session, then that session should automatically time out on the server, irregardless of what happens in the browser. Most application servers I have used provide a way to execute code when a session timeouts.
I'm having a bit of trouble cancelling an asynch postback. I have an update panel with an update progress which contains a cancel button so that the user can cancel the postback. When the user clicks a button to generate a report the update progress is shown. The report can take a bit of time as it has to loop through a thousand or so times creating an excel spreadsheet. If the user decides to cancel running the report for any reason then they can click the cancel button which I then call abortPostBack() in javascript which stops the update progress and the page is shown again. However, the user can't do anything else like navigate to another page as the server is still processing the loop. How would I stop the loop on the server processing when the user has clicked the cancel button? Any help appreciated!
Are you saying that a simple HTTP link is not accessible on the client side until the async postback is complete? If so, that sounds like a conundrum, since you either have to optimize your server side process, or set a smaller server-side request timeout. Either that or redesign your user-interaction to make the server side Excel generation process an asynchronous one, rather than synchronous, so that the user doesn't have to wait until the Excel generation is complete. You could fancy this up on the client side to then set a JavaScript timer to periodically query the server to see if the file was ready, and if so, indicate that to the user with and give them a download file link option, or something.
Otherwise, if you could invoke another AJAX request while waiting on that to return (which you may not to from the sound of it), you could simply perform a new HTTP request that "cancels" the long running process. But that seems like it would not work since the server is still handling the long running HTTP request. So I'd opt to investigate the options in my first paragraph.
If cancelling did allow an async HTTP request to be performed on the client side, then you could set a session state value to indicate that cancel was requested. Personally I wouldn't approach it this way. But if you did, then your long-running server-side process could periodically look for the existence of a session value. Say:
if (Session["cancel-me"] != null)
{
Session["cancel-me"] = null;
abortThisLongProcess();
}
Yep, even if you navigate away from the page using the browser back button, as soon as you click anything else that needs to post back to the server the page hangs until the long process has completed. Looks like there's no way of canceling so I will have to look at redesigning the Excel generation.
I haven't found a way to cancel the request that's running, but there's no real reason that you can't start a new one.
By default ASP.Net tries (it can't always) to apply an exclusive lock on the session object - as soon as one page reads it every other page request that passes the same session ID (by cookie or on the URL) has to wait for the first page to release the session.
It doesn't matter that the client has cancelled the request - the server will continue to lock the session until the original page finishes executing.
I think the solution is to do away with the ASP session entirely. Then when the user requests another page it begins immediately, even though the server is still processing the old request on another thread.