Jak ukončit spojení s klientem – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Jak ukončit spojení s klientem – PHP – Fórum – Programujte.comJak ukončit spojení s klientem – PHP – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Skřivy0
Duch
18. 6. 2008   #1
-
0
-

Ahoj,

řeším problém, jak ukončit spojení s klientem tak, aby script mohl pokračovat dál.

Ukázka toho, jak to myslím:

<?php

ignore_user_abort( true );

// Počátek scriptu - nějaký výpisy, zápisy do databáze, ...

echo "ok";

// Ukončení spojení s klientem

// Script po ukončení

// Tady bude nějaký kopírování - třeba 10 giga dat
// Nebo možná nějaký zabalování několika giga dat
// ... prostě věci, které se musí dělat dlouho

?>

Je to kvůli ajaxu, bohužel mi IE čeká až se stáhne celá stránka s výsledkem (ob_fush(); a podobný věci už jsem zkoušel - bohužel neúspěšně :\ )

Nahlásit jako SPAM
IP: 84.42.166.–
Reklama
Reklama
curo0
Newbie
18. 6. 2008   #2
-
0
-

A hodit to do neviditelného iframu?

Nahlásit jako SPAM
IP: 82.100.63.–
Prog.0
Věrný člen
18. 6. 2008   #3
-
0
-

Nemyslím, že to bude možné tak jednoducho.

Nagooglil som iba takéto riešenie http://www.mail-archive.com/php-general@lists.php.net/msg108210.html.
V skratke: Použiješ register_shutdown_function(). Zavoláš exit() a malo by sa stať že sa spojenie ukončí a vykoná fcia. Ale myslím, že sa čaká na vykonanie funkcie, a spojenie sa ukončí až potom, takže to asi bude na nič.

Napadlo ma ešte, že by sa to dalo vyriešiť tak, že tvoj script by iba spustil nejaký externý proces a skript sám by skončil. Spojenie s browserom by sa uzavrelo, no proces by bežal dalej. Našiel som: http://sk.php.net/manual/en/function.shell-exec.php#73490. No bojím sa, že ak zavoláš ten proces, tak sa tam ten script zastaví, kým sa proces neukončí, a exit môžeš zavolať až potom, takže zasa nič. Prípadne sa skús pohrabať tu: http://sk.php.net/manual/en/book.exec.php.



Ok, iný pohľad - skús ukončiť spojenie na strane klienta, prípadne ho vôbec neukončuj:

Z client-side scriptu (js?) odošli "ajax" request. Spustí sa server-side-script (php). Ten pripraví operáciu, ktorá sa má vykonať, skontroluje, či je všetko o.k. a odošle clientovi odpoveď typu "ok, idem na to" / "uz na tom pracujem" / "uz je to hotove" / "chyba" / etc... Php script sa odpoveďou neukončí, ale začne a bude sa vykonávať operácia...

Na strane klienta však nemusíš čakať až na ukončenie spojenia, ale odpoveď môžeš čítať hňed, ako dorazí. Takže hneď, ako dostaneš zo servera "ok, idem na to", alebo niečo podobné, zavoláš metódu abort() tvojho objektu xmlhttprequest a tým spojenie uzavrieš.

Mimochodom, vôbec neviem, prečo chceš to spojenie uzavrieť. Veď nech tam je. Ak ho nezrušíš, môžeš ho navyše využiť. Z bežiaceho skriptu na serveri môžeš priebežne odosielať priebeh procesu (percenta) a na strane klienta ich budeš môcť sledovať, a zobrazovať napríklad v podobe nejakého dorastajúceho prúžku (progressbaru). Taktiež, ak dôjde ku chybe počas vykonávanie tej operácie, budeš môcť užívateľa hneď informovať....


Dúfam že som ťa aspoň trocha nasmeroval ;-)

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Skřivy0
Duch
18. 6. 2008   #4
-
0
-

# Prog.

register_shutdown_function() + exit(): podle manuálu funguje pouze u PHP < 4.1

shell-exec nechci používat - musel bych zmenšit security pravidla na serveru



Spojení chci uzavřít kvůli mé neznalosti ajaxu a problém s IE - IE mi čeká až příjde celý výsledek stránky a pak pokračuje. Možná to jde ovlivnit na straně js, to jsem nezkoumal.

Nahlásit jako SPAM
IP: 84.42.166.–
Prog.0
Věrný člen
18. 6. 2008   #5
-
0
-

To Skřivy : Prirodzená cesta na to v php asi existovať nebude, takže na to budeš musieť vymislieť nejakú fintu. Nerozumiem, celkom, že spomínaš iba IE, ostatné browseri reagujú inak ? Ono by to malo závisieť od toho js kódu, čo sa bude robiť. Riešiť tu js a ajax by bolo offtopic.

btw, tiež nerozumiem: zmenšiť security. Veď by si presne nadefinoval práva len na ten jeden shell script na spustenie... Ale ani mne by sa takéto riešenie nepáčilo...

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Skřivy0
Duch
18. 6. 2008   #6
-
0
-

# Prog.: Ono je to s tou security trochu složitější. Server je postavený tak, že shell-exec vůbec nefunguje a fungovat nikdy nebude, protože by se pak muselo hodně zasahovat do nastavení systému.

Nahlásit jako SPAM
IP: 84.42.166.–
Prog.0
Věrný člen
18. 6. 2008   #7
-
0
-

Napadlo ma takéto php riešenie:

JS pošle request na nejaký php script. Ten pošle ďalší request na nejaký iný php script na tom istom serveri a hneď skončí => JS zaznamená koniec spojenia.

Druhý script nastaví ignore_user_abort( true ), vypne timeout a začne pracovať...

poslať request zo servera na server môžeš napr. cez fopen(), s použitím url wrappera, alebo fukciou virtual().
Môže sa jednať aj o jeden a ten istý script, len mu pošleš nejaký param...

Príklad:

do_something.php

<?php

ignore_user_abort( true );

if (@$_GET['do_it'])
{
set_time_limit(0);
switch(@$_GET['cmd'])
{
...
}
}
else
{
set_time_limit ( 5 );
fopen('http://server/do_something.php?cmd='.urlencode(@$_GET['cmd']).'&do_it=1');
}
?>

z js potom len zavolas http://server/do_something.php?cmd=urob_nieco



Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Skřivy0
Duch
18. 6. 2008   #8
-
0
-

To Prog. : jj, to mě taky napadlo, ale nelíbí se mi to, protože to znamená další celej http request, ale zatím asi nejlepší řešení.

Nahlásit jako SPAM
IP: 84.42.166.–
Skřivy0
Duch
18. 6. 2008   #9
-
0
-

To Prog. : hehe, tak problém: fopen bohužel čeká až script doběhne, čili jsme na začátku ...

Nahlásit jako SPAM
IP: 84.42.166.–
Prog.0
Věrný člen
19. 6. 2008   #10
-
0
-

To Skřivy : Čaká, aj keď pred tým nastavíš time_limit ? Uf... Môžeš sa pozrieť ešte na tú fn. virtual(). Ja len viem že taká nejaká je, no ešte som ju neskúšal.

Ale najlepšie by bolo riešiť to na strane javascriptu...

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Skřivy0
Duch
19. 6. 2008   #11
-
0
-

To Prog. : Boužel taky čeká. :\

Nahlásit jako SPAM
IP: 84.42.166.–
Prog.0
Věrný člen
19. 6. 2008   #12
-
0
-

To Skřivy : Skus ešte tak:

$f = fsockopen("www.server.cz", 80, $errno, $errstr, 5);

if ($f)
{
fwrite($f, "GET /do_something.php?cmd=...&doit=1 HTTP/1.1\r\n".
"Host: www.server.cz\r\n".
"Connection: Close\r\n\r\n");
fclose($f);
}

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Skřivy0
Duch
19. 6. 2008   #13
-
0
-

Super, poslední řešení už funguje ... díky

Nahlásit jako SPAM
IP: 84.42.166.–
Prog.0
Věrný člen
19. 6. 2008   #14
-
0
-

To Skřivy : Len by som tomu velmi neveril... Chcelo by to ešte prečítať si nejakú odozvu z toho socketu, či sa operácia spustila, lebo teraz nevieš, či nedojde ku chybe. Asi takto:

do_something.php

<?php
ignore_user_abort( true );

if (@$_GET['do_it'])
{
$ready = priprav_operaciu();
if ($ready)
{
echo "OK\r\n"; flush(); // odošle odpoveď
set_time_limit(0);
rob_operaciu();
}
else
{
echo "CHYBA\r\n";
exit();
}
}
else
{

$f = fsockopen("www.server.cz", 80, $errno, $errstr, 5);
if ($f)
{
fwrite($f, "GET /do_something.php?cmd=".urlencode(@$_GET['cmd'])."&doit=1 HTTP/1.1\r\n".
"Host: www.server.cz\r\n".
"Connection: Close\r\n\r\n");
$status = rtrim(fgets($f));
fclose($f);
}
// do ajax odpovede mozes zakomponovať hodnotu v premmennej $status
}

?>

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Prog.0
Věrný člen
19. 6. 2008   #15
-
0
-

Uf, sorry, zabudol som na http headery, tak ak to nahodou budeš robiť, tak mysli aj na ne.

Nahlásit jako SPAM
IP: 213.160.186.–
Prog.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 155 hostů

Podobná vlákna

Jak ukončit if bez returnu — založil Draffix

Jak ukončit jinou aplikaci — založil Hula

[Java6]Jak ukoncit thread? — založil shadius

SVCHOST - ukončit — založil Garret Raziel

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý