Как программно убить скрученный сервер веб-сокетов

Как вы программно убиваете сервер веб-сокетов? Я буду развертывать этот сервер в производстве наряду с другими вещами. И мне нравится создавать один скрипт на Python, который посылает всем сигнал об уничтожении. Я не могу понять, как убить эту штуку без прерывания пользовательской клавиатуры или kill -9.

sys.exit() не работает.

psutil и terminate() тоже не работали

import os
import psutil

current_system_pid = os.getpid()

ThisSystem = psutil.Process(current_system_pid)
ThisSystem.terminate()

У меня нет идей. Пока я убиваю его в командной строке с помощью команды kill -9.

Когда я убиваю его различными способами, он, как правило, видит это сообщение ниже, но скрипт все еще работает.

2020-12-12 12:24:54-0500 [autobahn.twisted.websocket.WebSocketServerFactory] (TCP Port 8080 Closed)
2020-12-12 12:24:54-0500 [-] Stopping factory <autobahn.twisted.websocket.WebSocketServerFactory object at 0x110680f28>

установка автобана:

pip install autobahn[twisted]

Код:

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
import sys
from twisted.python import log
from twisted.internet import reactor

class MyServerProtocol(WebSocketServerProtocol):

    def onConnect(self, request):
        print("Client connecting: {0}".format(request.peer))

    def onOpen(self):
        print("WebSocket connection open.")

    def onMessage(self, payload, isBinary):
        print("Text message received: {0}".format(payload.decode('utf8')))

        # echo back message verbatim
        # self.sendMessage(payload, isBinary)

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))


def StopWebsocketServer():
    PrintAndLog_FuncNameHeader("Begin")
    reactor.stop()
    PrintAndLog_FuncNameHeader("End")


if __name__ == '__main__':   
    # TODO remove the logging that came in the example
    log.startLogging(sys.stdout)

    factory = WebSocketServerFactory("ws://127.0.0.1:8080")
    factory.protocol = MyServerProtocol

    # note to self: if using putChild, the child must be bytes...
    reactor.listenTCP(Port_ws, factory)
    reactor.run()

Решение с использованием ответа @Jean-Paul Calderone:

    import os
    import signal
    os.kill(os.getpid(), signal.SIGKILL)

У меня есть внешний скрипт Python, который отправляет сигнал уничтожения каждому из моих скриптов Python. Сигнал уничтожения — это просто наличие файла, который должен искать каждый сценарий. Как только появляется этот сигнал уничтожения, каждый скрипт знает, что у него есть x секунд до того, как он будет уничтожен. Таким образом, у них есть несколько секунд, чтобы изящно закончить что-то.

Вы рассматривали os.kill()?

Diggy. 12.12.2020 19:53

os.kill действительно работал с signal.SIGKILL. Спасибо

LampShade 13.12.2020 14:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
429
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

twisted.internet.reactor.stop() это то, как вы останавливаете реактор. Обычно это приводит к завершению программы на основе Twisted (хотя, конечно, это не обязательно, если программа делает больше вещей после выключения реактора - но это необычно).

Однако похоже, что вы не хотите знать, какой код Python нужно запустить внутри процесса, чтобы завершить его. Вы хотите знать, что какой-то другой процесс может сделать с вашим процессом на основе Twisted, чтобы он завершился. Вы дали два решения - KeyboardInterrupt и SIGKILL. Вы не упомянули, почему ни одно из этих двух решений не подходит. Мне они кажутся хорошими.

Если вам не нравится SIGKILL (чего вам не должно быть, в конце концов, ваша программа может преждевременно умереть по многим причинам, и вы должны быть готовы с этим справиться), то вы, возможно, упустили из виду KeyboardInterrupt, так это то, что он просто исключение, которое вызывается внутри программы Python обработчиком SIGINT по умолчанию.

Если вы отправите SIGINT процессу на основе Twisted, то при обычном использовании это остановит реактор и позволит завершить работу в установленном порядке.

signal.SIGKILL сработало отлично. Спасибо. Я попробовал реактор.stop(), и по какой-то причине он останавливал сервер веб-сокетов, но не выходил из скрипта. Он вел себя так, как будто он все еще застрял в петле, но у меня нигде не было петель. Возможно, я сделал что-то не так, но SIGKILL делает именно то, что я хочу, поэтому я соглашусь с ним.
LampShade 13.12.2020 14:16

Другие вопросы по теме