Hello! Interested in the question - how can I properly stop the execution of a while loop with sleep inside. The fact is that I implement " long poll " to quickly update the information on the site (alerts, other information).

ESSENCE OF SCRIPT WORK

1. We send a GET request to the PHP page where the script is located.

2. The script starts the while loop .

3. In this cycle there are 2 conditions and sleep (1) at the end, which pauses the execution of the cycle.

- If if the cycle works for more than 30 seconds - stop the execution of the cycle, respectively, and the script.

- If a new information has appeared on the site, say β€œalert” - output the result to the user and stop the cycle.

PROBLEM If the user closes the browser window, or reloads the page, a new request for this script will be executed, which will start the cycle again. But at the same time, the previous execution of the while loop will not stop until at least one condition inside it is triggered. If the user sends a lot of requests to the page - the server's memory starts to load heavily and as a result everything hangs until all while stops performing.

QUESTION How to stop the execution of the loop and the script as a whole when you re-execute it or reload the page by the client? So far, at the moment I have done the following. When executing the script, we generate a random number, which we write to the variable and also with the session. Further inside while I do a condition in which the given variable should equal session value. If false, stop the loop. If we run the script on a new one, the session value changes and, accordingly, all previous while executing stops. Can I use this option? And how safe is it?

UPDATE.PHP

// ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ сСссию ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ $session = Session::instance(); $rand = rand(); $session->set('user_update_key', $rand); $key = $rand; $limit = 20; $seconds = 0; set_time_limit($limit + 1); while (TRUE) { if (Session::instance()->get('user_update_key') == $key) { if (Π΅ΡΡ‚ΡŒ Π»ΠΈ обновлСния. Ссли Π΅ΡΡ‚ΡŒ - Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ) { echo 'информация ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ'; flush(); exit; } if ($seconds == $limit) { // Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ†ΠΈΠΊΠ»Π° ΠΏΠΎ ΠΈΡΡ‚Π΅Ρ‡Π΅Π½ΠΈΡŽ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. echo 'Close'; flush(); exit; } $seconds++; } else { unset($session, $rand, $key, $notice, $mysession, $last_notice, $limit, $notise_return, $seconds); flush(); exit; } session_write_close(); sleep(1); session_start(); 

}

  • And if the malicious user generates a query with the same value of the variable? - VladD
  • The variable is generated in the php file itself. I'm not saying that everything is fine here. I myself do not like this implementation. Ideally, do it this way - the user closed the page, or updated it - everything, the script stopped. But this does not work out ( - qulery

3 answers 3

It seems that you are interested in two-way communication of the user with a long-running PHP process, and PHP processes between themselves during their execution. PHP for this is not sharpened, as already mentioned, but there are extensions that may be useful.

Without additional lotions, the session mechanism is suitable, or similar to its own, involving, for example, the database as "shared memory". In the first approximation, I would have done exactly the same thing as you.

Why do you want a long polling, and not a new one-time request once a second? VK comment widgets, let's say, just like that. If the web server is configured not to close every connection instantly, the chain of such requests will not slow down. (See KeepAlive setting for Apache)

Finally, you can look towards other technologies and protocols, for example. Flash and RTMP: a small flash drive in a web page that, via RTMP, communicates with the RED5 server, and receives / sends info via JS to a flash drive - real real time!

  • one
    @sergiks instead of rtmp it is desirable to use websockets , so that they are in the flash and in html5. - lampa
  • @lampa thanks, buddha to know. - Sergiks

Look for other options - just recently on HabrΓ© was an article about the nature and limitations of PHP . Other options are offered in the comments. For example, in this and in this .

    Well, as an option, write the time in the cookie, and not let the user perform the next request until it is executed ......

    • OK. And if the user starts writing his js with the ajax cycle via the console. Empty - qulery
    • and what will it give? - parks
    • This will result in the fact that if the user manually launches 100 script requests, 100 while will start and the server will be killed. - qulery
    • Then write down to the base - parks