4

由于没有更好的词,“交互式”客户端/服务器行为,我一直在努力思考如何让 Twisted 执行。

我设法将一对确实连接到服务的 Protocol 和 ClientFactory 类放在一起,并执行即时查询/响应(请参阅:connectionMade -> self.queryStatus)。这按预期成功并打印了来自 Factory 类的服务器响应。

我现在的问题是我将有必须导致数据发送的外部事件,同时始终监听潜在的传入数据。但是一旦 reactor.run() 循环开始,我不确定我的应用程序的其余部分是如何触发数据发送的。

从那以后,我尝试了几种不同的方法,但这是处理 recv 部分的最简单方法,如下所述:

class myListenerProtocol(LineReceiver):
    delimiter = '\n'

    def connectionMade(self):
        print("Connected to: %s" % self.transport.getPeer())
        self.queryStatus(1)

    def dataReceived(self, data):
        print("Receiving Data from %s" % self.transport.getPeer())
        ...
        self.commandReceived(self.myData)

    def commandReceived(self, myData):
        self.factory.commandReceived(myData)

    def connectionLost(self, reason):
        print("Disconnected.")

    def queryStatus(self, CommandValue):
        ...
        strSend = CommandValue # or some such
        self.transport.write(strSend)

class mySocketFactory(ClientFactory):
    protocol = myListenerProtocol

    def __init__(self):
        pass

    def buildProtocol(self, address):
        proto = ClientFactory.buildProtocol(self, address)
        return proto

    def commandReceived(self, myData):
        print myData
        reactor.stop() # It won't normally stop after recv

    def clientConnectionFailed(self, connector, reason):
        print("Connection failed.")
        reactor.stop()


def main():
    f = mySocketFactory()
    reactor.connectTCP("10.10.10.1", 1234, f)
    reactor.run()

我想这很简单,但是无数小时的大量示例和文档让我无法很好地理解我打算如何处理这种情况。

4

2 回答 2

1

我现在的问题是我将有必须导致数据发送的外部事件,同时始终监听潜在的传入数据。但是一旦 reactor.run() 循环开始,我不确定我的应用程序的其余部分是如何触发数据发送的。

“外部事件”?像什么?数据到达连接?太好了,让反应堆运行意味着您实际上可以处理这些数据。

或者,也许有人正在单击 GUI 中的按钮?尝试其中一个 GUI 集成反应器 - 再次,您无法处理这些事件,直到您运行反应器。

你可能会被卡住,因为你认为你的主要功能应该做reactor.run(),然后继续做其他事情。这不是它的工作方式。当您编写事件驱动程序时,您定义了所有事件源,然后在事件到达这些源时让事件循环调用您的处理程序。

于 2013-06-04T19:40:01.663 回答
-1

好吧,有很多方法可以做到这一点,而最好的方法实际上取决于您的应用程序的上下文,所以我不会在这里详细介绍一种方法,而是将您链接到我最近阅读的关于黑客新闻的阅读:

和很好的用例示例,尽管它可能不适用于您正在从事的工作(或者您可能已经阅读过它):

顺便说一句,你也可以看看擅长处理这类事情的 gevent 或 tornado。

如果您的其他“事件”来自 GUI 工具包(如 GTK 或 QT) ,请务必小心GIL,即使您只需要命令行事件,您也需要线程并且仍然要小心

最后,如果您想进行更多交互,您还可以为您的服务器编写不同类型的“对等点”,它们与您正在处理的不同用例进行交互(一个连接到 GUI 的客户端,另一个使用 CLI ,另一个带有数据库,另一个带有 SAAS 的 API 等。)。

换句话说,如果您的设计不起作用,请尝试改变您的观点!

于 2013-06-04T18:29:57.893 回答