Detecting Browser exit in PHP - php

I have looked at a few topics (here & google) regarding detecting browser exit in php and im not really any clearer on how to do so.
I tried the register_shutdown_function in PHP but that was executing even when i refreshed the browser page.
Can anyone help?
Thanks in advance

PHP is a server side language. Browser events are handled by DOM events. On "onunload" or "onbeforeunload" events, sending an AJAX call to a PHP file.
And in this other question there is a flavored explanation of what I'm saying.

Please explain what you want to do when the browser closes, to see if there perhaps is another way to do so.
A web server sends its response to the browser, and then (usually) closes the connection. You'd have to do something in Javascript, but that won't catch all conditions. You certainly can't detect it serverside.
It can be detected using the Javascript onbeforeunload or onunload functions, but that is absolutely not accurately, since it won't detect:
a browser crash
a browser exit
a computer shutdown
a link click on the page
when going Back in the browser
Also see this answer.
So for example when you want to log out users when they close the browser, you'd better use a "keepalive" mechanism instead of a "say goodbye" one. You can then log those users off on the server (e.g. using cron) whose sessions have not been active (i.e. who haven't sent a "keepalive") for more than X minutes.

I don't think there is any foolproof way to detect a browser close button in PHP or Javascript.
It is much safer and better to handle it via timer based polling OR just simple session timeouts on server side.

One solution that is at least fool resistant is to send a heartbeat to the server using Javascript and Ajax, then assuming that the browser window has been closed when the signal stops pulsing.
Another would be to use web sockets to maintain a constant connection until the browser window closes.
In any case it would take quite a bit of work from your part to set it up

Not just with PHP.
PHP runs server-side, and is far done processing your page by the time the user will have a chance to close their browser. You could technically detect if PHP was still processing the page and the user closes it, with a specific configuration. However, it is not ideal. See connection_aborted().
What you need to do is set up a long-polling connection with JavaScript, and monitor it server-side. You will then get an idea for when that window is closed. That connection could be made to your PHP script, allowing PHP to check connection_aborted(). Note that you will need to set up ignore_user_abort() for this to work, or configure PHP.ini accordingly.

Related

<a href="page.html> and <a href="page.php>: do these both trigger an interaction with the web server?

I have to solve this problem:
Explain what the following code snapshots do, and for each specify
whether it triggers an interaction (of the client/browser) with the server or
it is executed at the client side.
(iv) click here
(v) click here
Now, respectively they call for page.html and page.php from the web server. My instinct says this counts as an interaction (request-receive) of the client with the server in both cases, but the way the question is laid out seems to suggest that perhaps only the php link truly counts as an interaction.
Could anyone confirm the correct interpretation and perhaps clarify what counts as an interaction with the server.
Both trigger an interaction with the server, as your instinct said.
Without knowing the server setup, you don't even know if the HTML-file is served unmodified, or if the request is being rewritten and processed by any server side scripting language.
The question explicitly says the other option is being executed at the client side, which is definitely wrong for both. The only exception would be when the click event is intercepted, but that requires more code on the client side and that would have to be part of the question.
The code itself does no server interactions. Browser uses this code to draw a hyperlink, still no server interaction. As soon as the user clicks any of the links, the interaction between browser and server is triggered (no matter if it is a .html or .php, the server receives the request and decides how to handle it).
If the page is opened locally as file://C:/.../xxx.html, it interacts directly with the localhost, I don't know if this is considered a server interaction... The question seems a bit unclear to me.

How do i check for a change in a file that has been included in an HTML doc through an AJAX script?

I am writing a JavaScript for an in-browser IM client for the sake of practicing and learning JavaScript and AJAX.
I need to be able to check for a change in the file size of a text file that is being used as a temporary storage for 40-80 SQL entries that contain messages so that it can update the display.
At the moment I am using a setInterval function to periodically check for a change in file size using short PHP script, but this can cause issues, if the interval is to long, messages are delayed, if it is shorter, it means a lot of php scripts running very quickly, which takes up server resources.
What is the best way to do this if the main concern is to reduce server resource usage?
(I am running my server off of a rather low tech PC I've scraped together(2gb ram, 2.8ghz AMD seperon processor))
Preferably, I would want to do this using an AJAX event triggered by someone sending a message, I.E. When user B triggers the event that edits the file by pressing enter, that triggers a function on user A's side that updates the HTML file
Any ideas? I am open to any solution to this particular problem. I gave specific examples of what I want to happen in the specific languages in order to give a better idea of what it is I am attempting to do.
If there is a way to do this that isn't JavaScript/PHP, I'd also be open to exploring that as an option.
Doing this with PHP can be a bit cumbersome. You could try doing something like long polling where you keep the HTTP request open until the server has new data to send to the user. If messages are sent frequently, this might not be ideal. You might want to consider using event-driven web technologies like node.js with something like Socket.IO.
In any case, you'll likely want to maintain a connection with the server if you want to get the message in near real-time. There are ways to use WebSockets with PHP as well, but PHP isn't really the best for this because it's not designed to keep scripts running for long periods (also see What exactly entails setting up a PHP Websocket Server?).
Browsers & HTTP/ AJAX generally work by a "pull" model. The browser/ or AJAX sends the server a request, then the server answers a response.
There isn't generally much provision for the server to contact the browser, to "push" an event. This can however be simulated by a long-running request, to which the server writes data when the event/ or events occur.
For example, this could be a request that answers "empty" after a timeout of 10-30 seconds.. or the server returns & answers immediately, if there are event(s) in its queue.
With a Java server this is easy to do, and I've used this successfully for event notification in a major integration project a few years back.
However I'm not sure in PHP how much ability there is (probably very near zero) to maintain an overall server state, coordinate or communicate between threads/requests, or maintain event queues.
You could look into something like a Java webapp running on Tomcat. All you need is a basic web.xml and one Servlet class, and you can build just about anything from there.

Why does apache not process multiple requests from the same browser simultaneously

I'm not quite sure how to phrase this question correctly, so I'll start with the scenario I encountered.
I have a bit of processing in my web app that takes longer than I'd like the user to wait to have control of the page again, so I decided to have it processed by an ajax request.
The problem is, even though I offloaded this request into an ajax request, it seems that apache won't process any further requests until the original processor heavy request is complete.
I originally wanted to know how I could get around this issue, but have since decided that it might be a bad idea in general.
However, I'm still curious if anyone knows why apache behaves this way, and what (if any) configuration directive controls it. My original thought was KeepAlive, but disabling that didn't seem to change the behavior.
I am running php through mod_php if that makes a difference.
I appreciate any help getting pointed in the right direction!
Are you using file-based sessions? PHP will lock session files for each request and maintain that lock until you do a session_write_close() or the script terminates/exits. The side effect of this is that all requests become serial, since they're all contending for the same single resource (the session file).
I am sure it's the session file. I have the same problem. I run a request that is long such as a PHPMyAdmin SQL insert which takes multiple minutes to process. While it is processing I try to open a new tab in the same browser and go to any page on my website and it will not go there until the original PHPMyAdmin request is done.
If I open an incognito window in Chrome which is the same browser it works fine. If I open the website in any other browser it is fine.
So it is probably the file based session which is the default for PHP.
Others have mentioned going to memcached. You could also save sessions in the database.
Before having to go to memcached you could do all the session based stuff at the beginning. Copy the session variable into a temporary variable so you can close it then close it. And then if you need to set a session value later open it and make the change and then close it quickly.
Can you point to evidence that it's apache? Unless your apache setup isn't optimal, most likely your page wait is something else, maybe you have set your ajax call to be non-async?

failsafe for networked robot

I have a robot that I'm controlling via a browser. A page with buttons to go forward, reverse, etc is written in PHP hosted on an onboard computer. The PHP is just sending ASCII characters over a serial connection to a microcontroller. Anyway, I need to implement a failsafe so that when the person driving it gets disconnected, the robot will stop. The only thing I can think to do is to ping the person on the web page or something, but I'm sure there is a better way than that. The robot is connected either via an ad hoc network or a regular wireless network that is connected to the internet. Obviously if I go with the ping method then there will have to be a delay between the actual time disconnected and when it realizes it's been disconnected. I'd like this delay to be a small as possible, whatever the method used. I'd appreciate any ideas on how to do this.
Pinging a web client is somewhat unreliable, for you have to take into account, that the client ip might change.
On the other hand, you could emulate a "dead-man-button" via Ajax. Let the webpage send a defined command every now and then (maybe every 5 to 10 seconds). If the robot doesn't receive the message for some time, it can stop. The Ajax script could run in the background so the controlling user won't even notice anything.
This would of course mean, that your robot needs to have a counter which is incremented every second and reset when the message is received. The moment the timer variable is too high, FULL STOP
May I suggest you use a simple flash object embedded in the web browser to open a socket connection to a server on the robot? The server can be written in any suitable language - even PHP (cough).
Then it is a simple matter to detect immediately when the connection goes down, and implement your fail-safe approach.
HTTP is not a ideal protocol for robot control.
Good luck!
All I can think of is to include ajax code in your HTML that "pings" your server every X second. I believe that's what Facebook Chat does to know whether or not you are still online.
HTML 5 Web sockets might be the solution you are looking for but you have to consider that it won't be implemented by most of your users' browsers.
You might find this article interesting: http://www.infoq.com/news/2008/12/websockets-vs-comet-ajax.

PHP Jabber: if I login and check messages and disconnect, on the other users end I will show up as disconnected

Am not sure if what I am doing is absolutely correct. But here goes:
User logins into chat via web-based interface
User is informed of updates via Comet
User enters details which goto a PHP file which further connects to a Jabber server
Now the problem is that when the user wants to send a message, it's simple, run php in which i connect to jabber server and send the message. The problem arises when I am waiting for a message. Cause if I login and check messages and disconnect, on the other users end I will show up as disconnected.
Am I approaching this problem in a wrong way? Should I directly connect to the Jabber server (via javascript) instead of a PHP layer in between? How to recieve messages via PHP?
I haven't tried it out, but you might want to look at xmpphp. Secondly, you might want to consider keeping the user logged in to the XMPP server (aka a Jabber server) for as long as they're logged in to your website. You probably want to have a timeout of some kind in case they leave your website and don't come back.
As for whether or not you should connect via JavaScript, I don't see why you couldn't. I would suggest that you go for whatever seems the simplest to you. You might want to check out Strophe, which I hear good things about, for that case.
The only XMPP library that I've used extensively though is headstock, but that requires using python and Kamaelia.
this is an inherent problem (or feature) with http - there are no lasting connections (not really). you need a workaround, there is no real solution.
you could do it with java or flash, but that's not really nice (javascript 4tw!).
the other possibility would be to create an intermediate client what translates connections between the browser and the webserver to connections between the webserver and the jabber server. messy, but possible.
or maybe there is an API that helps with this.
directly connecting to the jabber server via javascript
i possibly slept through the latest ajax-inventions, but afaik you can only communicate with the host the source-html file comes from (ignoring greasmonkey and addons). no different domains, no different ports, period. unless you're going to teach your jabber server how to serve your chatpage-html to the browser, this will get problematic. moreover, staying connected doesn't even work, because that would require multipart-responses. those are only supported by mozilla, and this is why the ugly duckling COMET even exists in the first place. comet itself is a workaround to avoid the inability to hold connections while transfering data.
So the issue, as far as I can tell, is that when the Jabber user on the other end responds. The problem there, at least in part, is that the user is responding to another user on the Jabber server, yet you want the php script to be aware that this response has taken place without holding the connection open (which makes sense since the script is no longer running, probably).
One option, albeit a really silly one, is:
Have a php script that can broker a connection to the Jabber server for both sending and receiving for the user on your page,
Use AJAX to send messages for the user (the AJAX would point to the above script, the script would send the message.)
Have a Javascript infinite loop that pings the same script ever 10 seconds or so, checking in to see if there are messages. If there are, they get passed back to the client and output to the user.
There are only two issues with the above:
1) If the user isn't connected when the message is transmitted, will the php script still see/get the message?
2) A client side loop that makes ajax requests every 3 seconds would probably be a huge drain.
Solution 2:
OpenFire jabber server. It comes with a web chat client built in, and it has an addon called Fastpath, which is meant to handle HTML-based chats on the client end (like the "chat with an agent now!" feature on too many support pages.)
We use this at work and it is very customizable, can be integrated with other scripts (for instance, if you want a script that fills in the user details from their login, or adds some custom avatar, or whatever), and it (OpenFire) has tons of other extensions and addons that, if this isn't what you want, they probably have what you are looking for.

Categories