所以我有一个小的附带项目,它使用了来自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:])
希望这能有所帮助!