如何优雅退出应用程序以twistd开始?

law*_*sea 12 python twisted twisted.words twisted.application

我有一个jabber客户端正在从它的stdin读取并发布PubSub消息.如果我在stdin上获得EOF,我想终止客户端.

我第一次尝试sys.exit(),但这会导致异常,客户端不会退出.然后我做了一些搜索,发现我应该打电话reactor.stop(),但我无法完成这项工作.我的客户端中的以下代码:

from twisted.internet import reactor
reactor.stop()
Run Code Online (Sandbox Code Playgroud)

结果是 exceptions.AttributeError: 'module' object has no attribute 'stop'

我需要做些什么才能导致扭曲关闭我的应用程序并退出?

编辑2

原始问题是由一些符号链接导致模块导入混乱引起的.解决了这个问题之后,我得到了一个新的例外:

twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.
Run Code Online (Sandbox Code Playgroud)

异常后,twistd关闭.我想这可能被调用造成MyClient.loopMyClient.connectionInitialized.也许我需要将电话推迟到以后?

编辑

这是.tac我客户的文件

import sys

from twisted.application import service
from twisted.words.protocols.jabber.jid import JID

from myApp.clients import MyClient

clientJID = JID('client@example.com')
serverJID = JID('pubsub.example.com')
password = 'secret'

application = service.Application('XMPP client')
xmppClient = client.XMPPClient(clientJID, password)
xmppClient.logTraffic = True
xmppClient.setServiceParent(application)

handler = MyClient(clientJID, serverJID, sys.stdin)
handler.setHandlerParent(xmppClient)
Run Code Online (Sandbox Code Playgroud)

我正在调用它

twistd -noy sentry/myclient.tac < input.txt
Run Code Online (Sandbox Code Playgroud)

这是MyClient的代码:

import os
import sys
import time
from datetime import datetime

from wokkel.pubsub import PubSubClient

class MyClient(PubSubClient):
    def __init__(self, entity, server, file, sender=None):
        self.entity = entity
        self.server = server
        self.sender = sender
        self.file = file

    def loop(self):
        while True:
            line = self.file.readline()
            if line:
                print line
            else:
                from twisted.internet import reactor
                reactor.stop()

    def connectionInitialized(self):
        self.loop()
Run Code Online (Sandbox Code Playgroud)

nos*_*klo 7

from twisted.internet import reactor
reactor.stop()
Run Code Online (Sandbox Code Playgroud)

应该工作.事实上它并不意味着你的应用程序出了别的问题.我无法弄清楚你提供的信息有什么问题.

你能提供更多(全部)代码吗?


编辑:

好的,现在的问题是你没有停止自己的while True循环,所以它将继续循环并最终再次停止反应堆.

试试这个:

from twisted.internet import reactor
reactor.stop()
return
Run Code Online (Sandbox Code Playgroud)

现在,我怀疑你的循环对于事件驱动的框架来说不是一件好事.虽然你只是打印线条,但它很好,但取决于你想要做什么(我怀疑你不仅仅是打印线条)你必须重构那个循环来处理事件.


小智 5

reactor.callFromThread(reactor.stop)而不是reactor.stop.这应该可以解决问题.