在Twisted中关闭连接后退出Python程序



所以我有一个小的附带项目,它使用了来自autobahn twisted的python中的websockets。客户端和服务器之间的连接以及数据传输工作正常,但在TCP连接关闭后,我很难正常退出程序。她的代码是:

class MyClientProtocol(WebSocketClientProtocol):
    def onConnect(self, response):
        print("Server connected: {0}".format(response.peer))
    def onOpen(self):
        print("WebSocket connection open.")
        def hello():
            from twisted.internet import reactor
            self.sendMessage(u"Hello, world!".encode('utf8'))
            self.sendMessage(b"x00x01x03x04", isBinary=True)
            #self.factory.reactor.callLater(1, hello)
            #self.reactor.callFromThread(reactor.stop)
            #reactor.callFromThread(reactor.stop)
            #self.factory.reactor.callFromThread(reactor.stop)
        # start sending messages every second ..
        hello()
        return
    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))
    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))

def WebCon():
    import sys
    from twisted.python import log
    from twisted.internet import reactor
    log.startLogging(sys.stdout)
    factory = WebSocketClientFactory("ws://localhost:8080", debug=False)
    factory.protocol = MyClientProtocol
    reactor.connectTCP("127.0.0.1", 8080, factory)
    reactor.run()
    reactor.stop()
    print("Should exit")
    return

reactor.run()将永远运行。所以的两条线

reactor.run()
reactor.stop()

平均值:

永远奔跑。"永远"结束后,停止跑步。

你提问的方式有一条线索:你说你想"在TCP连接关闭后优雅地退出程序"。由于您的程序现在已经编写完成,您可以在程序准备好退出后优雅地退出程序。

连接关闭是一个事件。在Twisted中,对象上调用的方法会通知您事件。幸运的是,您已经获得了对象,甚至已经实现了适当的方法!你只需要更改

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

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

对于更惯用的解决方案,您应该真正使用端点(而不是connectTCP)来建立传出连接,并使用react(而不是reactor.run())来运行主循环。看起来你想写一个更像"连接,然后在我的连接上做一些事情,然后等待连接关闭,然后退出"的函数,而不是硬编码onClose来停止整个反应器。

看起来更像这样:导入系统从somewhere.i.dont.aknow导入(WebSocketClientProtocol,WebSocketClientFactory)

from twisted.internet.defer import Deferred, inlineCallbacks
from twisted.internet.task import react
from twisted.internet.endpoints import clientFromString
from twisted.logger import globalLogBeginner, textFileLogObserver
class MyClientProtocol(WebSocketClientProtocol):
    def __init__(self):
        self.finished = Deferred()
    def onConnect(self, response):
        print("Server connected: {0}".format(response.peer))
    def onOpen(self):
        print("WebSocket connection open.")
        self.sendMessage(u"Hello, world!".encode('utf8'))
        self.sendMessage(b"x00x01x03x04", isBinary=True)
    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))
    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))
        self.finished.callback(None)

@inlineCallbacks
def WebCon(reactor, endpoint="tcp:127.0.0.1:80"):
    globalLogBeginner.beginLoggingTo(textFileLogObserver(sys.stdout))
    factory = WebSocketClientFactory("ws://localhost:8080", debug=False)
    factory.protocol = MyClientProtocol
    endpoint = clientFromString(reactor, endpoint)
    protocol = yield endpoint.connect(factory)
    yield protocol.finished
react(WebCon, sys.argv[1:])

希望这能有所帮助!

相关内容

  • 没有找到相关文章

最新更新