@happyjuic

Как воспроизводить код при закрытии приложения?

Есть консольное приложение, хочу, чтобы как только работа приложения заканчивалась (неважно, закрыл ли ее юзер нажатием на крестик, через диспетчер задач, или программа просто "отработала" весь свой код). Надо, чтобы приложение отправляло на сервер условное сообщение "disconnected"

Как бы странно ни звучало, вообще не нашел чего-то подобного. Даже новомодные нейросети не справились (:
Спасибо
  • Вопрос задан
  • 253 просмотра
Пригласить эксперта
Ответы на вопрос 5
pickHabr
@pickHabr
Костыльных дел мастер
на клиенте можно отследить только целевое закрытие программы (нажатие соответствующей кнопки), для нецелевого завершения клиентского приложения можно нагородить костыль в виде дополнительной программы демона, который запускается при запуске основной программы, фиксирует PID основного приложения и по кд пингует его, когда PID пропал или присвоился другому отправлять сообщение на сервер, но это костыль и не спасет от ситуации закрытия всех программ через диспетчер задач, и даже если закрытие приложение удалось поймать на клиенте - как отправиь эту инфу на сервер если, допустим, на клиенте уже нет интернета

на сервер условное сообщение "disconnected"


просто на сервере отслеживать когда коннект оборвался, это может быть предусмотренное событие разрыва соединения, можно просто пинг (от сервера) понг (от клиента) реализовать, когда пинг не проходит - считаем, что приложение закрыли. тут может быть коллизия с тем, что приложение запущено, но отключился интернет например
Ответ написан
@Everything_is_bad
Даже новомодные нейросети не справились
а давай ты просто научишься гуглить?

https://docs.python.org/3/library/atexit.html
Ответ написан
неважно, закрыл ли ее юзер нажатием на крестик, через диспетчер задач, или программа просто "отработала" весь свой код

А ещё если вдруг пропало электричество или хулиган перерезал провода, ага :)

Вообще следующий способ предусматривает даже такие экстремальные случаи
Надо, чтобы приложение отправляло на сервер условное сообщение "disconnected"

Раз уж это клиент-серверное приложение, то почему бы прямо не отловить момент, когда соединение разорвано? В рамках TCP и так посылается специальное сообщение о том что клиент (или компьютер клиента) закрыл соединение (и есть механизм для отработки случая, когда соединение было оборвано не по инициативе клиента)

В качестве запасного варианта - по времени неактивности (например во время работы приложение может с некоторой периодичностью слать сообщение типа "ещё живой, ещё работаю", а как только оно перестало такие слать (пропустило X тактов) - считаем что disconnected)
Ответ написан
Комментировать
Vindicar
@Vindicar
RTFM!
Оставаясь внутри одного процесса - никак. Условно, вызов TerminateProcess() пришибёт целевой процесс без шанса на реакцию, как и некоторые другие ситуации. Ты можешь использовать atexit, как указали выше, но работать с сетью внутри него не получится. Работа с сетью вообще долгая штука.
Так что единственный вариант - запускать фоновый процесс-мониторилку, корректно отвязав его от основного процесса (чтобы не завершились вместе). Ну и иметь ввиду, что его тоже можно прибить, так что его надо перезапускать совместно. Тогда прибить оба процесса сразу будет труднее, хотя всё ещё возможно.
Ответ написан
Комментировать
warus
@warus
написать свой watchdog проверящий запущена ли программа:
например создать файл, открыть файл, удалить файл и не закрывать, пока программа работает файл существует, как она завершится, файл автоматом закроется, исчезнет - удалится.
Отследить что файл удалился либо самому: события от файловой системы ловить Inotify, либо воспользоваться сторонним утилитами: incron (аналогигичен chrontab), inotifywatch
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы