strophe / strophejs

Strophe.js is an XMPP library for JavaScript
http://strophe.im/strophejs
MIT License
1.46k stars 363 forks source link

Sending presence unavailable on unload using sendBeacon? #325

Open damencho opened 5 years ago

damencho commented 5 years ago

At some point, chrome rolled out a change that no XHR was sent during beforeunload and unload events, this was in Chrome 73. There was pushback and they quickly disabled that and now it is planned for Chrome 78. The recommended approach is to use sendBeacon, which is available on all major browsers nowadays. Are there any plans on changes to face that issue? Is there a way for the last presence unavailable to be sent using Navigator.sendBeacon() when using bosh?

https://stackoverflow.com/questions/55676319/ajax-synchronous-request-failing-in-chrome https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API https://bugs.chromium.org/p/chromium/issues/detail?id=952452

jcbrand commented 5 years ago

Are there any plans on changes to face that issue?

Not that I'm aware of.

Is there a way for the last presence unavailable to be sent using Navigator.sendBeacon() when using bosh?

I'm sure there'll be a way if someone takes the time to figure it out. I don't think it's necessarily a great idea to send out an unavailable presence because you don't know whether the person closed the tab or just reloaded the page.

damencho commented 5 years ago

In our case(jitsi-meet) it is very important to send the unavailable, as the next connection will produce new participant in the conference and for 60 seconds there will be a ghost participant in the room.

Now I see that we have access to the bosh proto internals and we can use the sid and rid to construct the bosh message, the same way we access lastResponseHeaders. So most probably we have what we need to use sendBeacon. I will just report the progress for completeness if someone needs the same.

jcbrand commented 5 years ago

it is very important to send the unavailable, as the next connection will produce new participant in the conference and for 60 seconds there will be a ghost participant in the room.

Have you considered just reattaching to the existing Strophe connection instead of creating a new one?

You can do that with the keepalive option. http://strophe.im/strophejs/doc/1.3.0/files/strophe-js.html

damencho commented 5 years ago

Have you considered just reattaching to the existing Strophe connection instead of creating a new one?

What will happen if I close the tab today and open it tomorrow, will it work? My question is what happens with stale data?

damencho commented 5 years ago

I don't think this is an option, cause we cannot make a difference whether this is closing the tab or reloading. When closing we want to signal that this user had left the conference. Isn't this something normal for all web apps using strophe, you close the window and you signal user is off, otherwise, there will be a period in which the server still thinks this user is on, till the bosh timeout expires?

jcbrand commented 5 years ago

What will happen if I close the tab today and open it tomorrow, will it work? My question is what happens with stale data?

The BOSH session will time out and the user will go offline. If you store data in sessionStorage, then it'll be cleared.

When closing we want to signal that this user had left the conference. Isn't this something normal for all web apps using strophe

Not necessarily, which is why the keepalive option is there. For some applications people are browsing around in a website where you want a persistent chat connection. In this case you definitely don't want to send an unavailable presence every time the person navigates to a different page in the site.

there will be a period in which the server still thinks this user is on, till the bosh timeout expires?

Yes, that's the drawback to this approach. Sounds like in your case it makes more sense to send an unavailable presence. It's not like people regularly reload the tab during video calls.

jcbrand commented 5 years ago

It would be great if you could this feature to Strophe itself (not in a plugin) and manage it with a Strophe.Connection option, much like keepalive, so that when the connection is created, you can set the option to determine whether you want to send an unavailable presence or not.

damencho commented 5 years ago

Hum, but this will make strophe window dependent. Is this ok?

jcbrand commented 5 years ago

It should be possible to make this conditional, see for example the code in this PR: #321