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

Joe*_*ose 2 twisted websocket python-2.7 autobahn

所以我有这个小方案项目,它使用来自高速公路扭曲的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"\x00\x01\x03\x04", 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
Run Code Online (Sandbox Code Playgroud)

Gly*_*yph 7

reactor.run()永远奔跑.所以这两行

reactor.run()
reactor.stop()
Run Code Online (Sandbox Code Playgroud)

意思:

永远奔跑."永远"完成后,停止运行.

你提出问题的方式有一个线索:你说你想在TCP连接关闭后 "优雅地[退出]程序".由于您的程序现在正在编写,因此您可以在程序准备退出后正常退出程序.

连接关闭是一个事件.在Twisted中,您可以通过在对象上调用的方法来通知事件.幸运的是,你已经有了这个对象,你甚至已经实现了适当的方法!你只需要改变

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

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

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

这看起来更像是这样:从somewhere.i.dont.know import导入sys(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"\x00\x01\x03\x04", 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:])
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!