更新:为了便于阅读,以下是如何在反应堆停堆前添加回调:

reactor.addSystemEventTrigger('before', 'shutdown', callable)

最初的问题如下。
如果我有一个客户机连接到一个服务器,它在反应堆主回路中冷却,等待事件发生,当我按下ctrl-c时,我得到一个“与另一端的连接以一种非干净的方式丢失:连接丢失”。我如何设置它,以便知道何时发生键盘中断,以便我可以做正确清理并断开连接?或者,如果可能的话,我如何实现一种不涉及ctrl-c的更干净的关机方式?

最佳答案

如果您真的,真的很想特别地捕获C-C,那么您可以用Python应用程序通常的方法来实现这一点-使用signal.signalSIGINT安装一个处理程序,它可以做您想做的任何事情。如果从处理程序调用任何扭曲的API,请确保使用reactor.callFromThread,因为几乎所有其他扭曲的API对于从信号处理程序调用都是不安全的。
但是,如果您真的只是想插入一些关闭时间清理代码,那么您可能希望使用IService.stopService(或者实现它的机制,reactor.addSystemEventTrigger)。
如果您使用的是twistd,那么使用IService.stopService很容易。您已经有了一个至少连接了一个服务的Application对象。您可以添加另一个方法来完成关闭工作。该方法允许返回一个stopService。如果是这样,则关闭过程将暂停,直到触发Deferred这样可以很好地清理连接,即使这涉及到更多的网络(或任何其他异步)操作。
如果您不使用Deferred,那么直接使用twistd可能更容易。您可以安装一个在关闭前触发器,它将在相同的情况下被调用。此触发器(仅限任何可调用对象)也可以返回一个reactor.addSystemEventTrigger以延迟关闭。这是通过调用IService.stopService来完成的(在启动关机之前的某个时间,这样每当发生关机时它就已经注册了)。
service.tac给出了创建和使用自定义服务的示例。
wxacceptance.py给出了使用Deferred并将关机延迟(任意)3秒的示例。
这两种机制都会在反应堆停止时通知您。这可能是由于C-C击键引起的,也可能是因为有人使用了reactor.addSystemEventTrigger('before', 'shutdown', callable),或者是因为某个地方调用了addSystemEventTrigger。它们都会导致反应堆停堆,反应堆停堆总是处理停堆事件触发器。

10-04 18:46