2013-02-07 58 views
1

下面的代碼摘自Twisted關於AMP的文檔(link)。當向d添加回調函數時,會自動添加一個「協議」參數,並在調用reactor.run()時自動運行延遲。Twisted:在使用pyglet-twisted時從終點調用Deferred的方式

def connect(): 
    endpoint = TCP4ClientEndpoint(reactor, "127.0.0.1", 8750) 
    factory = Factory() 
    factory.protocol = AMP 
    return endpoint.connect(factory) 

d = connect() 
def connected(protocol): 
    return protocol.callRemote(
     RegisterUser, 
     username=u'alice' 
d.addCallback(connected) 

reactor.run() 

在我的代碼,一切是完全一樣的,只是我一直在使用pyglet捻(link)與cocos2d的,所以我不能叫reactor.run(),因爲反應堆開始在同一時間被作爲應用程序。

如果我調用reactor.run(),我得到一個錯誤,說明reactor已經在運行。

如果我不這樣做,推遲的似乎不會被調用。

我一直在試圖與reactor.callLater,reactor.callWhenRunning調用它,但都需要一個參數。傳入「無」不起作用。

所以我的問題是,我應該如何讓這個延期運行而不調用reactor.run()。

謝謝!

回答

1

Twisted的API很少會在沒有運行反應堆的情況下成功。反應器負責的I/O。你必須有一個正在運行的反應堆才能建立連接(不管你是使用端點對象還是其他的API來這樣做)。

據我所知,pyglet整合反應堆不會自動啓動。有些東西必須稱之爲run方法。你的問題表明你沒有打電話給我,所以我很好奇叫它。

當我修改你的榜樣,使之完整和可運行,並添加錯誤報告,就像這樣:

from pygletreactor import install 
install() 

from twisted.internet import reactor 
from twisted.internet.endpoints import TCP4ClientEndpoint 
from twisted.internet.protocol import Factory 
from twisted.protocols.amp import AMP 
from twisted.python.log import err 

def connect(): 
    endpoint = TCP4ClientEndpoint(reactor, "127.0.0.1", 8750) 
    factory = Factory() 
    factory.protocol = AMP 
    return endpoint.connect(factory) 

d = connect() 
def connected(protocol): 
    return protocol.callRemote(
     RegisterUser, 
     username=u'alice') 
d.addCallback(connected) 
d.addErrback(err) 

reactor.run() 

然後我得到我所期望的行爲,這是用於連接嘗試,然後失敗(因爲我沒有在任何地方運行AMP服務器):

Unhandled Error 
Traceback (most recent call last): 
Failure: twisted.internet.error.ConnectionRefusedError: Connection was refused by other side: 111: Connection refused. 

也許你可以將它與你的完整程序進行比較,並找到一個重要的區別。

+1

謝謝!我忘了提及我修改了pyglet來調用reactor.run()。我再看了一遍這個問題,結果發現問題出在Cocos2d被硬編碼以使用pyglet的事件循環的方式,因此pygletreactor中的循環沒有被調用。 – Robert

1

經過更多研究,我發現原因deferredendpoint.connect()返回沒有被調用是一個與cocos2d的錯誤。

cocos.director的底部,其中pyglet.app.event_loop被分配處理導演在director.event = event_loop.event行中的事件。

這需要改爲使用pygletreactoreventloop來代替。所以上面的代碼需要更改爲以下內容:

import pygletreactor 
event_loop = pygletreactor.EventLoop() 
director = Director() 
director.event = event_loop.event 
相關問題