扭曲工厂的时间延迟

时间:2017-04-24 06:58:21

标签: python twisted

我不知道如何在twisted.internet.loopingCall()

中使用twisted.internet.ClientFactory之类的内容

我需要编写python脚本,扫描目录以查找带有电话号码的传入文件,读取它们,并使用使用yaypm库的YATE twisted python模块进行调用。

client_factory = yaypm.TCPDispatcherFactory(start_client)
reactor.connectTCP(host, port, client_factory)
reactor.run()

yaypm.TCPDispatcherFactorytwisted.internet.ClientFactory派生的start_client是成功连接后将执行的函数。

如果start_client仅进行演示通话:

def start_client(client_yate):
    d = dialer(client_yate)
    d.call(caller, target)

一切都好。

dialer是实现yaypm.flow逻辑的对象,完整描述位于http://docs.yate.ro/wiki/YAYPM:Bridge_and_then_unbridge

我需要在start_client

中写下这样的内容
d = dialer(client_yate)
files = os.listdir(input_directory)
for filename in files:
    <read caller and target numbers from file>
    d.call(caller, target)
    time.sleep(interval)

我知道在主线程中使用sleep函数会导致死锁。 我该如何实现上面的算法?

1 个答案:

答案 0 :(得分:1)

如果您使用sleep()装饰器,

twisted.internet.task.deferLater就像inlineCallbacks调用一样。以下是使用ClientFactory

的简化示例
from twisted.internet import reactor, task
from twisted.internet.defer import inlineCallbacks
from twisted.internet.protocol import Protocol, ClientFactory


class DoNothing(Protocol):
    def __init__(self, connection_callback):
        self.connection_callback = connection_callback

    def connectionMade(self):
        self.connection_callback()
        return


class ConnectionClientFactory(ClientFactory):
    def __init__(self, connection_callback):
        self.connection_callback = connection_callback

    def buildProtocol(self, addr):
        return DoNothing(self.connection_callback)



def sleep(delay):
    # Returns a deferred that calls do-nothing function
    # after `delay` seconds
    return task.deferLater(reactor, delay, lambda: None)


@inlineCallbacks
def repeat_forever(message):
    while True:
        print(message)
        yield sleep(1)


if __name__ == '__main__':
    repeat_forever('running')

    factory = ConnectionClientFactory(lambda: repeat_forever('connected'))
    reactor.connectTCP('example.com', 80, factory)
    reactor.run()

上面的代码基本上就是你的库对你传入的回调所做的。正如你所看到的,对repeat_forever('running')的调用与客户端连接后调用的调用同时进行。