Как вы программно убиваете сервер веб-сокетов? Я буду развертывать этот сервер в производстве наряду с другими вещами. И мне нравится создавать один скрипт на 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 действительно работал с signal.SIGKILL. Спасибо
twisted.internet.reactor.stop()
это то, как вы останавливаете реактор. Обычно это приводит к завершению программы на основе Twisted (хотя, конечно, это не обязательно, если программа делает больше вещей после выключения реактора - но это необычно).
Однако похоже, что вы не хотите знать, какой код Python нужно запустить внутри процесса, чтобы завершить его. Вы хотите знать, что какой-то другой процесс может сделать с вашим процессом на основе Twisted, чтобы он завершился. Вы дали два решения - KeyboardInterrupt и SIGKILL. Вы не упомянули, почему ни одно из этих двух решений не подходит. Мне они кажутся хорошими.
Если вам не нравится SIGKILL (чего вам не должно быть, в конце концов, ваша программа может преждевременно умереть по многим причинам, и вы должны быть готовы с этим справиться), то вы, возможно, упустили из виду KeyboardInterrupt, так это то, что он просто исключение, которое вызывается внутри программы Python обработчиком SIGINT по умолчанию.
Если вы отправите SIGINT процессу на основе Twisted, то при обычном использовании это остановит реактор и позволит завершить работу в установленном порядке.
signal.SIGKILL
сработало отлично. Спасибо. Я попробовал реактор.stop(), и по какой-то причине он останавливал сервер веб-сокетов, но не выходил из скрипта. Он вел себя так, как будто он все еще застрял в петле, но у меня нигде не было петель. Возможно, я сделал что-то не так, но SIGKILL делает именно то, что я хочу, поэтому я соглашусь с ним.
Вы рассматривали os.kill()?