2009-10-09 15 views
5

Jestem odpowiedzialny za część zapleczową API napisaną w PHP, która jest używana głównie przez klienta Flash. To, co dzieje się teraz, to: klient Flash wykonuje wywołanie, backend ładuje niezbędne dane, wykonuje niezbędne przetwarzanie i przetwarzanie końcowe, rejestrowanie i buforowanie, a następnie zwraca wynik do klienta.PHP + gzip: zamknij połączenie i kontynuuj wykonywanie

To, co chciałbym mieć, to zwrócić dane do klienta tak szybko, jak to możliwe, zamknąć połączenie, a następnie wykonać wszystkie czynności, na które klient nie musi się martwić. Może to sprawić, że interfejs API będzie wyglądał znacznie lepiej. Następujące propozycje tutaj:

http://php.net/manual/en/features.connection-handling.php

faktycznie działa, oprócz tego, że muszę wyłączyć kodowanie gzip w celu uczynienia go pracy, co nie jest bardzo praktyczny. Używamy mod_deflate w apache, więc rozwiązanie, które współdziała z tym byłoby idealne, ale rozważałoby również inną metodę gzip naszej zawartości, jeśli jest to konieczne.

Wydaje się, że wydaje się być, tak jak powinien być sposób, aby Apache wiedział "Wysłałem Ci wszystkie dane, które zamierzam wysłać," ale nie mogę znaleźć czegoś takiego.

Dla tych, którzy się zastanawiają, tak, mogę wcześnie wypróżnić wyniki, ale klient Flash nie przetworzy ich, dopóki połączenie nie zostanie zamknięte.

Odpowiedz

3

Możesz spróbować podzielić go na dwie strony.

Na pierwszej stronie wykonaj niezbędne przetwarzanie, a następnie załaduj drugą stronę za pomocą curl i die().

To spowodowałoby zakończenie i zamknięcie pierwszej strony, niezależnie od przetwarzania drugiej strony.

tj:

Strona 1:

Strona 2:

<?php 

// Do other stuff.... 

?> 

Zobacz http://www.php.net/curl

+0

Dzięki. Jestem świadomy kilku obejść tego problemu, niektóre bardziej eleganckie niż inne, ale naprawdę chciałbym znaleźć sposób, aby powiedzieć Apache, aby przestał czekać na wyjście i zamknąć połączenie. :) –

0

Jest to rodzaj hack, aby to zrobić poprzez umieszczenie kodu chcesz wykonać po zamknięciu połączenia w ramach metody zwrotnej zarejestrowanej przez register_shutdown_function();

+0

Ooh, błyszczące! Spróbuję tego jutro. –

+0

Bez powodzenia. Następujący wydrukuje dodatkowe bzdury i zabiera pełny czas wykonania, aby zamknąć połączenie, gdy używasz mod_deflate: funkcja sleepLongTime() {print "nie możesz tego zobaczyć"; spać (30); } ob_end_clean(); register_shutdown_function ("sleepLongTime"); nagłówek ("Connection: close \ r \ n"); ignore_user_abort (true); ob_start(); echo ("Użytkownik tekstu zobaczy"); ob_end_flush(); flush(); ob_end_clean(); die(); –

0

@ Theo.T ponieważ system komentarz zniekształcone bzdura z mojego kodu, jestem umieszczenie go tutaj:

bez powodzenia. Poniższe wypisuje bzdury dodatkowym i ma czas pełnego wykonania, aby zakończyć połączenie przy użyciu mod_deflate:

function sleepLongTime() { 
    print "you can't see this"; 
    sleep(30); 
} 
ob_end_clean(); 
register_shutdown_function('sleepLongTime'); 
header("Connection: close\r\n"); 
ignore_user_abort(true); 
ob_start(); 
echo ('Text user will see'); 
ob_end_flush(); 
flush(); 
ob_end_clean(); 
die(); 
0
set_time_limit(0); 
header("Connection: close"); 
header("Content-Length: " .(strlen($stream)+256)); 
ignore_user_abort(true); 

echo $stream; 
echo(str_repeat(' ',256)); 
@ob_flush(); 
@flush(); 
@ob_end_flush(); 

your_long_long_long_long_function_here(); 

to powie użytkownikowi zamknąć połączenie po otrzymaniu wszystkich $stream. ale należy uważać, aby nie powtórzyć wszystko przed header strony u wiedzą: P

przypadku wysyłania danych binarnych (swf) mogą być potrzebne, aby usunąć „+256” i echo(str_repeat(' ',256)); ale w tym przypadku kodu „może” nie jeśli przesłane dane mają mniej niż 256 bajtów.

-1

Dzisiaj spotkał się także w tej sprawie, po kilku testach ok, znalazłem ten sposób działa:

dwuetapowo:

  1. upewnić się, że wyjście skrypt php nie jest z kodowaniem gzip, rozwiązanie może odnosić się do tego link:

    <IfModule mod_env.c>
    SetEnvIfNoCase Request_URI "\.php$" no-gzip dont-vary
    </IfModule>

Dodaj powyższy plik do .htaccess pod stroną internetową prj, a następnie automatycznie usuń go za pomocą apache gzip.

  1. Ponieważ niektórzy ludzie mówili na features.connection-handling.php,

    set_time_limit(0); 
    ignore_user_abort(true);  
    // buffer all upcoming output - make sure we care about compression: 
    if(!ob_start("ob_gzhandler")) 
        ob_start();   
    echo $stringToOutput;  
    // get the size of the output 
    $size = ob_get_length();  
    // send headers to tell the browser to close the connection  
    header("Content-Length: $size"); 
    header('Connection: close');  
    // flush all output 
    ob_end_flush(); 
    ob_flush(); 
    flush();  
    // close current session 
    if (session_id()) session_write_close(); //close connection 
    
    // here, do what you want. 
    
+0

Prosi gzip, a ty nie dajesz gzipowej odpowiedzi ... to nie pomaga. – brunoais