Mój skrypt jest wywoływany przez serwer. Z serwera otrzymam ID_OF_MESSAGE
i TEXT_OF_MESSAGE
.
W moim skrypcie obsłużę przychodzący tekst i wygeneruję odpowiedź z parametrami: ANSWER_TO_ID
i RESPONSE_MESSAGE
.
Problem w tym, że wysyłam odpowiedź na incomming "ID_OF_MESSAGE"
, ale serwer, który wyśle mi wiadomość do obsługi, ustawi swoją wiadomość jako dostarczoną do mnie (to znaczy, że mogę wysłać mu odpowiedź na ten identyfikator), po otrzymaniu odpowiedzi http 200.
Jednym z rozwiązań jest zapisanie wiadomości w bazie danych i utworzenie crona, który będzie działał co minutę, ale muszę natychmiast wygenerować wiadomość z odpowiedzią.
Czy jest jakieś rozwiązanie, jak wysłać do serwera odpowiedź http 200 i kontynuować wykonywanie skryptu php?
Dziękuję bardzo
header("Content-Encoding: none")
fastcgi_finish_request()
na koniec musiałem dodaćWidziałem tutaj wiele odpowiedzi, które sugerują użycie,
ignore_user_abort(true);
ale ten kod nie jest konieczny. Wszystko to polega na zapewnieniu, że skrypt będzie kontynuował wykonywanie, zanim zostanie wysłana odpowiedź w przypadku przerwania pracy przez użytkownika (poprzez zamknięcie przeglądarki lub naciśnięcie klawisza Escape, aby zatrzymać żądanie). Ale nie o to pytasz. Prosisz o kontynuowanie wykonywania PO wysłaniu odpowiedzi. Wszystko, czego potrzebujesz, to:Jeśli obawiasz się, że praca w tle potrwa dłużej niż domyślny limit czasu wykonywania skryptu PHP, trzymaj
set_time_limit(0);
się góry.źródło
Jeśli korzystasz z przetwarzania FastCGI lub PHP-FPM, możesz:
Źródło: https://www.php.net/manual/en/function.fastcgi-finish-request.php
Wydanie PHP nr 68722: https://bugs.php.net/bug.php?id=68772
źródło
Spędziłem kilka godzin nad tym problemem i otrzymałem tę funkcję, która działa na Apache i Nginx:
Możesz wywołać tę funkcję przed długim przetwarzaniem.
źródło
filter_input
funkcję, która czasami zwraca NULL. zobaczyć ten wpis użytkownika o szczegółachZmodyfikował nieco odpowiedź przez @vcampitelli. Nie myśl, że potrzebujesz
close
nagłówka. Widziałem zduplikowane zamknięte nagłówki w Chrome.źródło
Używam do tego funkcji register_shutdown_function.
http://php.net/manual/en/function.register-shutdown-function.php
Edycja : powyższe nie działa. Wygląda na to, że wprowadziła mnie w błąd stara dokumentacja. Zachowanie register_shutdown_function zmieniła się od PHP 4.1 łącza łącza
źródło
Nie mogę zainstalować pthread i żadne poprzednie rozwiązania nie działają. Znalazłem tylko następujące rozwiązanie do pracy (ref: https://stackoverflow.com/a/14469376/1315873 ):
źródło
w przypadku użycia php file_get_contents, zamknięcie połączenia nie wystarczy. php nadal czeka na wysłanie eof wiedźmy przez serwer.
moim rozwiązaniem jest przeczytanie „Content-Length:”
tutaj jest próbka:
response.php:
Zwróć uwagę na "\ n" w odpowiedzi na zamkniętą linię, jeśli nie na fget read while wait eof.
read.php:
Jak widać, ten skrypt nie może czekać około eof, jeśli długość treści jest osiągnięta.
mam nadzieję, że to pomoże
źródło
Zadałem to pytanie Rasmusowi Lerdorfowi w kwietniu 2012 roku, cytując następujące artykuły:
Zasugerowałem opracowanie nowej funkcji wbudowanej w PHP, aby powiadomić platformę, że nie będą generowane żadne dalsze dane wyjściowe (na stdout?) (Taka funkcja może zająć się zamknięciem połączenia). Rasmus Lerdorf odpowiedział:
Rozumiem jego punkt widzenia i popieram jego opinię w przypadku niektórych aplikacji / scenariuszy ładowania! Jednak w niektórych innych scenariuszach rozwiązania z vcampitelli i wsp. Są dobre.
źródło
Mam coś, co może skompresować i wysłać odpowiedź i pozwolić na wykonanie innego kodu php.
źródło
Istnieje inne podejście i warto je rozważyć, jeśli nie chcesz manipulować nagłówkami odpowiedzi. Jeśli uruchomisz wątek w innym procesie, wywołana funkcja nie będzie czekać na odpowiedź i wróci do przeglądarki ze sfinalizowanym kodem http. Będziesz musiał skonfigurować pthread .
Gdy wykonamy $ continue_processing-> start (), PHP nie będzie czekać na wynik powrotu tego wątku, a zatem o ile rozważany jest punkt końcowy. Zrobione.
Kilka linków do pomocy w pthreads
Powodzenia.
źródło
Wiem, że to stary, ale prawdopodobnie przydatny w tym momencie.
Tą odpowiedzią nie popieram rzeczywistego pytania, ale jak poprawnie rozwiązać ten problem. Mam nadzieję, że pomoże to innym ludziom rozwiązać takie problemy.
Sugerowałbym użycie RabbitMQ lub podobnych usług i uruchomienie obciążenia w tle przy użyciu instancji roboczych . Istnieje pakiet o nazwie amqplib dla php, który wykonuje całą pracę za Ciebie, aby użyć RabbitMQ.
Profesjonaliści:
Neg:
źródło