我有一个问题。我有一个echoserver将接受客户端和处理他的要求,它返回结果给客户端。
假设我有两个客户端,一个客户端需求处理时间将是10秒,两个客户端需求处理时间将是1秒。
当两个客户端同时连接到服务器时。如何同时运行两个客户端任务,并将响应返回给先完成的特定客户端。
我读到我们可以用python twisted来解决这个问题。我已经试过运气了,但我做不到。
请帮我解决这个问题
您的代码(https://trinket.io/python/87fd18ca9e)在异步设计模式方面有许多错误,但我将只解决最明显的错误。有一些对time.sleep()
的调用,这是阻塞代码,导致代码停止,直到睡眠函数完成运行。异步编程的第一条规则是不要使用阻塞函数!别担心,这是一个非常常见的错误,Twisted和Python异步社区可以帮助你:)我将为你的服务器提供一个简单的解决方案:
from twisted.internet.protocol import Factory
from twisted.internet import reactor, protocol, defer, task
def sleep(n):
return task.deferLater(reactor, n, lambda: None)
class QuoteProtocol(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.factory.numConnections += 1
@defer.inlineCallbacks
def recur_factorial(self,n):
fact=1
print(n)
for i in range(1,int(n)+1):
fact=fact*i
yield sleep(5) # async sleep
defer.returnValue(str(fact))
def dataReceived(self, data):
try:
number = int(data) # validate data is an int
except ValueError:
self.transport.write('Invalid input!')
return # "exit" otherwise
# use Deferreds to write to client after calculation is finished
deferred_factorial = self.recur_factorial(number)
deferred_factorial.addCallback(self.transport.write)
def connectionLost(self, reason):
self.factory.numConnections -= 1
class QuoteFactory(Factory):
numConnections = 0
def buildProtocol(self, addr):
return QuoteProtocol(self)
reactor.listenTCP(8000, QuoteFactory())
reactor.run()
主要差异在recur_factorial()
和dataReceived()
。recur_factorial()
现在利用Deferred
(搜索inlineCallbacks
或协程的工作方式),它允许函数在结果可用后执行。因此,当接收到数据时,将计算阶乘,然后将其写入最终用户。最后是新的sleep()
函数,它允许异步睡眠函数。我希望这对你有帮助。继续阅读Krondo博客