2015-06-26 23 views
2

因此,我有這個使用高速緩存中的websockets進行扭曲的小型項目。客戶端和服務器之間的連接以及數據傳輸完美地工作,但是在TCP連接關閉後我很難退出程序。她的代碼是:在Twisted中關閉連接後退出Python程序

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 
+0

也許使用'quit()'方法會是一條路嗎? – JPeroutek

+0

嘗試系統,退出和退出,他們都沒有工作。 –

回答

5

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() 

對於更地道的解決方案,你真的應該使用endpoints,不connectTCP,讓你的外出連接,react,不reactor.run(),跑你的主循環。它看起來像你想寫一個功能,讀取更像「連接,然後做我的連接上的東西,然後等待連接關閉,然後退出」而不是硬編碼onClose停止整個反應堆。

這會看起來更像是這樣的: 進口SYS 從somewhere.i.dont.know進口(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:]) 

希望這有助於!

相關問題