我試圖學習圍繞這些新穎的「工廠」式網絡庫的方法。 Twisted帶來了很多好評,但對我來說卻是一場絕對的噩夢,因爲我對lambda不熟悉,因此我真的不確定如何遵循演示代碼的做法。扭曲/放大器聯網:迴應所有客戶,而不僅僅是一個請求
演示客戶端:
from twisted.internet import reactor, defer
from twisted.internet.protocol import ClientCreator
from twisted.protocols import amp
from ampserver import Sum, Divide
def doMath():
d1 = ClientCreator(reactor, amp.AMP).connectTCP(
'127.0.0.1', 1234).addCallback(
lambda p: p.callRemote(Sum, a=13, b=81)).addCallback(
lambda result: result['total'])
def trapZero(result):
result.trap(ZeroDivisionError)
print "Divided by zero: returning INF"
return 1e1000
d2 = ClientCreator(reactor, amp.AMP).connectTCP(
'127.0.0.1', 1234).addCallback(
lambda p: p.callRemote(Divide, numerator=1234,
denominator=0)).addErrback(trapZero)
def done(result):
print 'Done with math:', result
defer.DeferredList([d1, d2]).addCallback(done)
if __name__ == '__main__':
doMath()
reactor.run()
演示服務器:
from twisted.protocols import amp
class Sum(amp.Command):
arguments = [('a', amp.Integer()),
('b', amp.Integer())]
response = [('total', amp.Integer())]
class Divide(amp.Command):
arguments = [('numerator', amp.Integer()),
('denominator', amp.Integer())]
response = [('result', amp.Float())]
errors = {ZeroDivisionError: 'ZERO_DIVISION'}
class Math(amp.AMP):
def sum(self, a, b):
total = a + b
print 'Did a sum: %d + %d = %d' % (a, b, total)
return {'total': total}
Sum.responder(sum)
def divide(self, numerator, denominator):
result = float(numerator)/denominator
print 'Divided: %d/%d = %f' % (numerator, denominator, result)
return {'result': result}
Divide.responder(divide)
def main():
from twisted.internet import reactor
from twisted.internet.protocol import Factory
pf = Factory()
pf.protocol = Math
reactor.listenTCP(1234, pf)
print 'started'
reactor.run()
if __name__ == '__main__':
main()
據我瞭解,客戶端p.callRemote(Sum, a=13, b=81)
和p.callRemote(Divide, numerator=1234, denominator=0)
部分叫Math.sum(13, 81)
和Math.Divide(1234, 0)
,因爲工廠對象的設置爲Math
類。不知何故,當客戶端收到來自服務器的返回值時,子功能Done(result)
被調用,它將東西打印到屏幕上。
這很棒,但是我的理解很糟糕,而且每一篇文檔似乎都期望達到這種理解水平。
我真正想要做的是將數據從客戶端發送到服務器,並從服務器發送到連接的多個客戶端。一旦交換結束,這種方法似乎會忘記客戶端,並阻止客戶端進行任何其他工作。
人們可能希望每一天都可以使用此功能。我如何理解這一點?
編輯:我試圖爲客戶端調用一個「檢查」功能,但這似乎是它會淹沒我的服務器的請求只是迴應「沒有報告」。此外,它增加了延遲,因爲客戶端只在需要時收到新數據,而不是實際可用時。工廠 - 反應器佈局似乎沒有公開我需要存儲的客戶信息,以便隨意對其進行響應。
Lambda是一種定義函數而不給它命名的方法;一個匿名函數。文檔顯示了它們與功能的關係。 http://docs.python.org/reference/expressions.html#lambda話雖如此,我認爲使用'CLientCreator'的'doMath()'中的代碼相當糟糕。它違反了「Python的禪宗」(嘗試在交互式Python會話中導入該文件)。 –
@RolandSmith,您對Twisted示例質量的看法將通過http://twistedmatrix.com/trac/newticket更有建設性地表達爲文檔缺陷報告。我不會說文檔是完美的,但提問者試圖理解的例子的質量與問題無關。 – Glyph
@RolandSmith @RolandSmith這不是一個嚴格的lambdas精確定義,因爲它還有一些巧妙的變量範圍 – Basic