12

我有一个 jabber 客户端,它正在读取其标准输入并发布 PubSub 消息。如果我在标准输入上得到 EOF,我想终止客户端。

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

from twisted.internet import reactor
reactor.stop()

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

我需要做什么才能让twistd 关闭我的应用程序并退出?

编辑 2

最初的问题是由一些符号链接弄乱了模块导入引起的。解决该问题后,我得到了一个新异常:

twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.

异常发生后,twistd 关闭。我认为这可能是由调用MyClient.loopin引起的MyClient.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)

我正在调用

twistd -noy sentry/myclient.tac < input.txt

这是 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()
4

3 回答 3

7
from twisted.internet import reactor
reactor.stop()

应该工作。事实上,它并不意味着您的应用程序有其他问题。我无法从你提供的信息中找出问题所在。

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


编辑:

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

尝试这个:

from twisted.internet import reactor
reactor.stop()
return

现在,我怀疑您的循环对于事件驱动框架来说不是一件好事。虽然您只是打印行,但这很好,但取决于您真正想要做什么(我怀疑您会做的不仅仅是打印行),您必须重构该循环以处理事件。

于 2011-03-17T20:48:52.300 回答
6

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

于 2016-04-20T08:49:26.517 回答
1

我曾经这样做(在非扭曲调用应用程序的 sigint 处理程序中):

reactor.removeAll()
reactor.iterate()
reactor.stop()

我不是 100% 确定这是正确的方式,但twisted 很高兴

在 tac 中启动的同一个应用程序由 twistd 信号处理程序直接处理,我发现了这个问题,因为我有一些 rpc 客户端请求,我会在退出之前等待并处理结果,看起来 twistd 只是在杀死反应堆而不让通话结束

于 2012-11-24T04:24:46.730 回答