2011-10-19 24 views
1

我有一個Twisted/Thrift服務器使用TTwisted協議。我希望保持客戶端連接處於打開狀態,直到發生特定事件(我通過回調通過Twisted反應器通知此事件)。阻止使用扭曲的節點呼叫

class ServiceHandler(object): 
    interface.implements(Service.Iface) 

    def listenForEvent(self): 
     """ 
     A method defined in my Thrift interface that should block the Thrift 
     response until my event of interest occurs. 
     """ 
     # I need to somehow return immediately to free up the reactor thread, 
     # but I don't want the Thrift call to be considered completed. The current 
     # request needs to be marked as "waiting" somehow. 

    def handleEvent(self): 
     """ 
     A method called when the event of interest occurs. It is a callback method 
     registered with the Twisted reactor. 
     """ 
     # Find all the "waiting" requests and notify them that the event occurred. 
     # This will cause all of the Thrift requests to complete. 

如何快速從我的處理程序對象的方法返回,同時保持阻塞Thrift調用的錯覺?


我從扭曲的啓動觸發初始化節儉處理程序:

def on_startup(): 
    handler = ServiceHandler()      
    processor = Service.Processor(handler)         
    server = TTwisted.ThriftServerFactory(processor=processor,     
     iprot_factory=TBinaryProtocol.TBinaryProtocolFactory())     
    reactor.listenTCP(9160, server) 

我在PHP客戶端連接:

$socket = new TSocket('localhost', 9160); 
    $transport = new TFramedTransport($socket); 
    $protocol = new TBinaryProtocol($transport); 
    $client = new ServiceClient($protocol); 
    $transport->open(); 
    $client->listenForEvent(); 

最後一次調用($client->listenForEvent())成功使得它交給服務器並運行ServiceHandler.listenForEvent,但即使該服務器方法返回twisted.internet.defer.Deferred()實例,客戶端也會立即收到一個空數組,並且I ge t時的異常:

異常「TTransportException」有消息「TSocket:超時 閱讀從本地主機4個字節:9160到本地端口38395」

回答

2

你應該能夠返回從listenForEvent一個延遲。後來handleEvent應該觸發返回的Deferred(或那些返回的Deferreds)來實際生成響應。

+0

我試過這樣做。我的問題可能是我需要使用客戶端的TTwisted傳輸嗎?我正在使用來自PHP的TFramedTransport。 – ide

+0

返回延期工作。問題是我的客戶端套接字的超時只有750毫秒。 – ide

1

您所看到的錯誤似乎表明傳輸未被構建(Twisted需要它以便事先知道每條消息的長度)。而且,Thrift服務器支持從處理程序返回延遲,所以這更加奇怪。你有沒有試過返回defer.succeed(「一些價值」),看看延期實際上是否工作?然後,您可以移動到此以檢查它是否完全正常工作:

d = defer.Deferred() 
    reactor.callLater(0, d.callback, results) 
    return d