Execute API after close the browser in Angular - javascript

i need to execute a Api if the browser closed, example break out,
closing the browser from the user, crash of pc, ext ext.
This function is in my component, i dont call this function anywhere,I think it should automatically activate.
#HostListener('window:beforeunload', ['$event'])
beforeunloadHandler(event) {
this.postService.unsetPost(this.postId).subscribe();
}
But dont work.

In my opinion the better idea is making the heartbeat api that sends requests every N seconds to notify server that the session is active and the user is online. On the server check every M minutes if there was no heartbeat requests for more than N seconds: if it is so - execute the API request(what you wanted to execute on crash).

Related

Angular 6: Trying to make synchronous call (delete) on browser close event (beforeunload/unload event of browser)

Actually, I want to update a flag in Db using a service call(Delete method) once the user close the browser. I am able to detect browser close action using onbeforeunload and onunload events but async call doesn't work for me(sometimes in debugging mode it works fine but on higher env it doesn't work).
Then, I tried to make sync request but then I found that Chrome now disallows synchronous XHR during page dismissal when the page is being navigated away from or closed by the user.
check link : https://www.chromestatus.com/feature/4664843055398912
I have tried new XMLHttpRequest() as sync, fetch api also Navigator.sendBeacon() but unfortunately nothing works for me.
Please suggest something which works because I have visited so many posts but nothing works for me.
Thanks in advance.
I have some solution for this. Hope so any one of them solves your issue.
constructor() {
window.onbeforeunload = ()=>{
//call API here
}
}
In your component constructor write above code
OR
In my opinion the better idea is making the heartbeat api that sends requests every N seconds to notify server that the session is active and the user is online. On the server check every M minutes if there was no heartbeat requests for more than N seconds: if it is so - execute the API request(what you wanted to execute on crash).
OR
'beforeunload' would be trigger when refreshing pages, closing tab, or closing the browser.
#HostListener('window:beforeunload', ['$event'])
beforeUnload(e: Event) {
e.returnValue = false;
}
OR
It is not possible to ensure that every time an user exits a browser page a specific function will be triggered. The reason is that the browser could close the window for many reasons. Yes it could be a user action but this is not the only case. For example The browser could crash.
In my case I will have to find another strategy to track the time the user stays on the page. For example I am planning to send a lot of API calls before the user exits with all the informations I need to understand his stay on the page. I will update the answer when I will reach a good solution. Anyway I will still wait for better answers.
You can use the fetch API.
The syntax would be:
fetch('API', {
method: 'POST', // Other opn are also supported like GET,PUT DELETE
body: '',
keepalive: true
});
Just an additional read:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Ember js run function when user closes window

I have an ember application where users are stored in a MySQL database. When a user exits (ie. closes their browser window), they need to be deleted from the database. I have the following code in one of my route files:
setupController: function () {
$(window).on('beforeunload', () => {
this.get('currentUser').delete();
});
},
In my testing this only seems to delete the user from the database maybe 70-80% of the time, and somehow it seems to be random whether it works or not. I'm guessing this is because sometimes the function isn't run in time before the browser has closed the window. How can I ensure the code to delete a user is executed every time a user exits?
It wouldn't work this way. Reason: browser interrupts any requests (even ajax) to backend when user closes window/tab.
I suggest to implement cleanup on backend side. What you need is store last time when user performed some action and delete those who did not make any requests in some period of time (for example, if there was no requests in 1 hour, you can be pretty sure that user closed browser window). You can also perform "ping" requests from your ember app to your backend once in a while, so idle users will not be deleted.

Hub.start - wait for finish

I'm using SignalR to transferring commands from client to server without refreshing the page. When the client enter some of my web pages, I'm starting a new hub connection. Like this:
var hub = $.connection.siteControllerHub;
$.connection.hub.start();
This "start()" function takes some time (+-5 seconds). mean while, the page is already finished loading and the user start using my UI. SingalR cannot serve the user, until it's finish loading the connection.
I'm know that I'm can use the async approach with the done() register:
$.connection.siteControllerHub.start().done(function () {
// On finish loading...
});
But this kind of operations is not suitable for me, since if I'm using this - I'm need to disable the UI until this event happens. And this not cool at all.
I'm prefer that loading of the page will takes longer but when it's done, everything will be ready for use.
What do you think? How do you recommend to implement it?
Thank you.
5 seconds is not normal. Anyway you can queue the messages and when done is called take the queued messages and send to server. Look here for example
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/aa239a7bb9d79346cacd16ea1ee97946b2d5d44b/SignalR.EventAggregatorProxy.Client.JS/signalR.eventAggregator.js#L165

Close server-side chat connections before unload in javascript

On my website, I have built a chatroom with support for multiple rooms. When a user joins the room, a session is placed into the database so that if they try to join the room again in another browser window, they are locked out.
It works like this
1. Join the chatroom page
2. Connect to chatroom #main
If the user has a session in the database for #main
--- Block user from joining
else
--- Load chatroom
When the chatroom is closed client side or the user terminates there connection with the /quit command, all of their sessions are deleted, and this works fine.
However
There is a possibility that users will just close the browser window rather than terminating their connection. The problem with this is that their session will stay in the database, meaning when they try to connect to the room, they are blocked.
I'm using this code onbeforeunload to try and prevent that
function disconnect() {
$.ajax({
url: "/remove-chat-sessions.php?global",
async: false
});
};
This is also the function called when the user types the /quit command
The problem
The problem with this is that when I reload the page, 5 times out of 10 the sessions have not been taken out of the database, as if the ajax request failed or the page reloaded before it could finish. This means that when I go back into the chatroom, the database still thinks that I am connected, and blocks me from entering the chatroom
Is there a better way to make sure that this AJAX call will load and if not, is there a better alternative than storing user sessions in an online database?
Edit:
The reason users are blocked from joining rooms more than once is because messages you post do not appear to you when the chatroom updates for new messages. They are appended to the chatroom box when you post them. This means that if users could be in the same chatroom over multiple windows, they would not be able to see the comments that they posted across all of the windows.
In this situation you could add some sort of polling. Basically, you request with javascript a page every X time. That page adds the user session to the database. Then there's a script executing every Y time, where Y > X, that cleans old sessions.
The script that is called every X time
...
// DB call (do as you like)
$All = fetch_all_recent();
foreach ($All as $Session)
{
if ($Session['time'] < time() - $y)
{
delete_session($Session['id']);
}
}
The script that javascript is calling every X time
...
delete_old_session($User->id);
add_user_session($User->id, $Chat->id, time());
The main disadvantage of this method is the increment in requests, something Apache is not so used to (for large request number). There are two non-exclusive alternatives for this, which involve access to the server, are:
Use nginx server. I have no experience in this but I've read it supports many more connections than Apache.
Use some modern form of persistent connection, like socket.io. However, it uses node.js, which can be good or bad, depending on your business.

what is the difference between close timeout and heartbeat interval in socket.io

Well as the question says what's the difference between close timeout and heartbeat interval parameters in socket.io
I read about them in the github page for socket.io
https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
But,couldn't quite understand the difference as to how are they related and if the values for both should be same or not in the case when I am manually configuring them.
Some more materials regarding this topic I came about --------------------
https://groups.google.com/forum/?fromgroups#!topic/socket_io/2hn52Udb-3A
Advantage/disadvantage of using socketio heartbeats
Socket.io "connection" event fired on every client heartbeat?
Is it safe to set a high close timeout on socket.io?
The documentation indeed isn't very clear.
As far as I understand it (also looking at the code):
close timeout sets a sort of 'grace period' when either the client or the server closes the connection: instead of closing it immediately, it will first wait close timeout seconds; if, within that period of time, the client decides to reconnect, send data, or receives data from the server, the connection will be reused (and the timeout will be cleared). Otherwise, when nothing has happened after the timeout, the connection is really closed;
heartbeat timeout: if, after this many seconds, the client hasn't responded to a heartbeat message from the server, the server will consider the connection to be lost (or the client to be non-responsive) and will close it;
heartbeat interval: this sets the interval between heartbeat messages (used by the server to check if the client is still connected); by default, it sends a message every 25 seconds;
close timeout and heartbeat timeout aren't really related, I don't think they have to have the same value.
EDIT: as for close timeout and heartbeat interval, I'm not sure. It could be that the heartbeat-message will cancel the close timeout, but it that were true, the default values that socket.io sets (25 and 60 seconds, respectively) don't make much sense.
EDIT #2: heartbeat-messages don't seem to cancel the close timeout, so they are unrelated.

Categories