I'm working on a Ruby on Rails application with Action Cable. Watching the logs, I've noticed that when I put my phone to sleep that the WebSocket is closed automatically, so further updates are not received. However, on wake (directly to the page, or opening the browser again and giving the tab focus) the connection is immediately re-established.
I want to refresh the page at this moment so that it's up-to-date. The "focus" event is not useful, as it will trigger whenever desktop users bounce between windows or tabs.
What event can I use to reload the page on wake? Something must be available, as Action Cable is reconnecting (though I realize it may be using the focus event as well and simply checking if a connection exists or not).
Related
I have a web application running in one or more browser tabs/windows. I also have a SharedWorker, which is connected to every single one tab/window and is also communicating with some server over websocket. To this point everything works as expected and without any problems.
There, I also have a single popup window (opened automatically or with user interaction, it doesn't matter) with some SIP/WebRTC plugin. After it's opened, I can communicate with it over the same SharedWorker as everything else and that's OK.
SharedWorker also keeps (or, at least, is trying) information about every connected tab/window - based on connect event in worker and beforeUnload in every other tab/window. Not the best solution, but only one I found working.
Everything runs on the same domain, in the same location.
Now, I can't find any solution to:
get the popup window handle from other tab/window than its opener, nor it's not possible to transfer handle to SharedWorker
react to close of popup window every time, cause in some point that window worker port gets lost
focus popup window from every other tab/window, cause there's no handle to it
I'm using a web framework where everything gets passed through a websocket. New / updated DOM elements are shipped over to the browser, events get shipped back to the server. Works great. Except when the websocket gets closed.
This happens...
when using desktop/mobile Safari's browser navigation buttons are used to leave & come back to the page
on mobile Safari after a timeout when switching to a different app, tab or screen locking
when the WiFi goes down etc.
After that the user simply sees a normal looking page, but everything is obviously dead as no more updates happen and no more events get relayed to the server. I'd like to simply refresh the page in that case. Either everything goes back to normal or the user sees a connection error in case of no network etc.
I tried poking around in the framework's code, adding "window.location.reload(true);" to the "onclose" handler for the websocket kinda does the trick. My state is 100% on the server, so reloading the page will just fix things.
Assuming I can't modify / fix the web framework I'm using, and it doesn't have any onConnectionLost client-side event, what's my best option to detect this scenario and reload the page? Are there any events like 'onPageDisplayedButNotProperlyReloaded', 'onPageVisibleButHasBecomeStaleInTheMeantime', 'onWebSocketsClosed' for me to use? Can I just open some dummy websocket and reload the page when it gets closed or something? Any other good way to detect this?
Thanks!
I'm having an issue where closing my Chrome App too quickly after completing a stage corrupts the save data. This is because it's in the middle of saving some data.
Is there any way to keep the Chrome App open for a few seconds after the user presses close or alt+f4? Or another solution that maybe has a popup telling the user that the app is saving and will close automatically?
You can use the chrome.runtime.onSuspend.addListener( function ) method to specify some code to run when the user quits the app. As stated in the chrome documentation, any code running or triggered in the background/event page will keep the program alive for a short time to allow these processes to end. Remember to register this event listener method in your background/event page before the user has a chance to quit.
Additional information here:
https://developer.chrome.com/extensions/runtime#event-onSuspend
Here's the situation:
I have a web-based ticket application, multiple users.
One problem that might occur (and does happen in the old version I'm replacing) is that user1 opens a ticket, edits it, and saves it. But while he was editing it, user2 also opened and saved the ticked. The changes user2 made will be lost/overwritten by user1.
To prevent this I implemented a locking mechanism, it's fairly simply:
On opening a ticket the PHP script checks for existing locks.
If it doesn't find any, it locks & opens the document.
In JS, setTimeout() and an XmlHttpRequest call to unlocks the ticket after 10 minutes (works w/o problems).
I also set an unload event to unlock the ticket when closing/moving away from the window/tab
The problem sits in step 4: The unload event (& it's friend beforeunload) just doesn't work well enough to implement this reliably (for this feature to have any serious meaning, it needs to be reliable), many browsers don't always fire it when I would like it to be fired (Like pressing back button, hitting F5, closing tab, etc. This varies per browser)
The only alternative I can come up with is using a setTimeout() and XmlHttpRequest() call to a php script to tell it the page is still open. If this "heartbeat" monitor fails we assume the user moved away from the ticket and unlock the document.
This seems horribly inefficient to me and quickly leads to many requests to the server with even a few users.
Anyone got a better idea on how to handle this?
It needs to work in IE8+ and other modern browsers (ideally, Firefox, Webkit, Opera). I don't care about IE6/IE7, our organization doesn't use those).
Using heartbeat pings via XHR is the way to go. Depending on the use case you might also want to send them after the user stopped typing in a field instead of every x seconds - this would ensure the page being kept open but inactive would not keep it locked.
If you send those XHRs after the user stopped typing, use one of the keydown/up/press events and a debounce / throttle script to send the request only when the user stops typing for e.g. 5 seconds and one every x seconds (in case it's likely enough the user will be typing for a long time).
Maybe it's not the best solution, but it's worth looking into it : websockets.
You could establish a connection with the server at page load and when the connection fails (ie the client does not respond to the ping), you can unlock the ticket.
Using something like socket.io ensures you that this procedure will work even on ie8.
The main advantage is that you do not send a request every n seconds, but the server sends you a ping every n seconds and you don't have to care about unload/beforeunload events. If the client doesn't respond to the ping, unlock the ticket.
The main disadvantage is that you need a server to handle all your websocket connections, which can be done in almost any server-side language, but it can be a bit harder than a simple web-service (in case of xhr polling)
Implementing ajax heartbeats or unload handlers to unlock the document automatically is tricky.
You problem is that even if you have support for beforeunload in all browsers that you target, it still might not be called if the browser crashes or the user falls asleep.
Look at how webdav works. You explicitly aquire a lock before you start edit, then you save and release the lock explicitly.
Other users can see who has acquired a lock and admins can release locks that has been left behind by accident.
I am working on a multiplayer chess game as a Facebook app.
If one player leaves the game by closing the browser the other player should get a notification. So if one player closes the Browser, a unlink function should be called to unlink the player. This works fine with onunload outside Facebook.
The problem is, that the Facebook apps are loaded in iframes and the onunload event doesn't work there.
So I need a way to call a function inside an iframe when a user is closing the browser.
This is probably not the answer you are looking for but "logging off" on unload will never work reliably. For an extreme example, consider the case where the browser crashes or is killed via the Windows task manager. So you better implement an additional mechanism to detect whether a user left. Typically this is done by sending a request to the server periodically. If this request isn't received for a significant time (meaning something that cannot be caused by a slow connection or other hiccups) you unlink the user.
That said, I tested Firefox 4 and MSIE 8 and both correctly fire unload event on the frame if the tab or the browser is closed. Chrome 12 doesn't do that, that's probably the browser you have been testing with. I consider it a Chrome bug.