Как убить сеанс PHP?


Эта общая тема поднималась ранее, здесь, здесь, здесь, и, без сомнения, в других местах Интернета. В моем случае, в отличие от них, зависание возникает из-за блокирующего сокета, который никогда не получает сообщения, и, возможно, именно поэтому описанные там решения не сработали для меня. Я разрабатываю в тандеме приложение на C++, которое взаимодействует со скриптом php через локальное соединение с сокетом, и когда приложение на C++ выходит из строя, оно оставляет сокет php-скрипта в ожидании для сообщения, которое никогда не придет. Я пробовал использовать session_destroy и session_unset (сначала вызывая их в скрипте перед session_start), но они не работают; даже выход и перезапуск браузера не помогают. Я могу остановить сеанс только в том случае, если удалю session_start, перезагрузлю скрипт и затем завершу сеанс через клиент. Как я могу завершить сеанс, не проходя через это?

Правка: Я забыл упомянуть, что я также пытался отключить сокет с помощью

socket_set_option($socket,0, SO_RCVTIMEO, array("sec"=>1, "usec"=>0));

Но Я получил ошибку "недопустимая операция", и она не сработала.

Правка 2: Установка тайм-аута вручную, следуя подсказке здесь, сработала достаточно хорошо. Я до сих пор не знаю, как, в общем, убить сеанс, который, например, застрял в бесконечном цикле, но ладно.

Author: Community, 2011-04-24

2 answers

Может быть, вы можете дать сокету тайм-аут? например, socket_select имеет параметр времени ожидания.

Значение 1000s в качестве тайм-аута может быть слишком большим, потому что apache, возможно, убил процесс раньше (см. max_execution_time в php.ini)

 1
Author: Florian, 2011-04-24 15:59:55

Как я могу завершить сеанс, не проходя через это?

Проблема, с которой вы столкнулись , не , которая будет решена путем прекращения сеанса.

Зависание возникает из блокирующего сокета, который никогда не получает сообщение

Если вы используете обработчик сеанса PHP по умолчанию, это означает, что PHP заблокировал этот файл. Ни один другой процесс PHP не сможет манипулировать сеансом, пока существует эта блокировка.

Здесь у вас есть несколько вариантов.

Во-первых, рассмотрите реализацию собственных процедур сохранения сеанса , что означает, что вы полностью контролируете, существует ли какая-либо блокировка данных сеанса. Вы можете просто вообще не включать блокировку, что позволит запущенному, но зависшему PHP-скрипту продолжать работать в мирном блаженстве. Это самый сложный вариант.

Во-вторых, вы уверены, что долго работающий скрипт сокета должен записать сеанс данные? Если нет, вы можете просто завершить сеанс раньше и снять блокировку, позвонив session_write_close. Это снимет блокировку, хотя на самом деле это не приведет к завершению длительного сценария при закрытии сокета.

В-третьих, посмотрите на использование тайм-аутов сокетов в вашем длительном сценарии. Я не уверен, какой именно метод вы используете для работы с сокетами здесь, и у меня очень мало опыта работы с ними в PHP, поэтому я не могу дать конкретную рекомендацию по функциям.

 3
Author: Charles, 2011-04-24 15:57:16