Как убить сессию PHP? - PullRequest
       22

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

4 голосов
/ 24 апреля 2011

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

Edit: я забыл упомянуть, я также пытался тайм-аут сокета с

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

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

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

Ответы [ 2 ]

3 голосов
/ 24 апреля 2011

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

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

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

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

У вас есть несколько вариантов здесь.

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

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

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

1 голос
/ 24 апреля 2011

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

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

...