【问题标题】:Send commands to twisted server向扭曲服务器发送命令
【发布时间】:2017-01-01 07:25:04
【问题描述】:

我有一个简单的扭曲 TCP 服务器,用于从另一个应用程序发送和接收数据。建立连接后,我就可以与此应用程序通信并向其发送消息。

我希望能够有一个外部模块命令何时以及将什么发送到第 3 方应用程序(而不是在连接时)。例如,这是我的服务器代码:

from twisted.internet import reactor, protocol

# Twisted
class Tcp(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)
        print 'data received: ', data
        # do something with data


    def connectionMade(self, msg):
        # Want to only transport message when I command not immediately when connected
        self.transport.write(msg)


class TcpFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Tcp()

reactor.listenTCP(8001, TcpFactory())
reactor.run()

我有另一个模块(由 GUI 界面操作),它定义了要发送的消息,并且该消息需要作为“msg”传递到 connectionMade

最好的方法是什么?

【问题讨论】:

    标签: python tcp twisted


    【解决方案1】:

    您的第 3 方呼叫将发生在 connectionMade 内,不应直接呼叫。 connectionMade 是一个 Twisted 回调,它在那里表示客户端在另一端。由你决定之后会发生什么。因此,您可以执行一系列 Deferreds/callbacks 之类的操作,这些回调采用 self.transport(其中包含相关的客户端数据)。在这一系列回调中,您将拥有自己的逻辑

    1. 与第 3 方通信
    2. 验证客户端
    3. 向客户端发送消息

    这是它的要点:

    def connectionMade(self):
        d = Deferred()
        d.addCallback(self.thirdPartyComm).addErrBack(self.handleError)
        d.addCallback(sendMsg)
        d.callback(self.transport)
    
    def thirdPartyComm(self, transport):
        # logic for talking to 3rd party goes here
        # 3rd party should validate the client then provide a msg
        # or raise exception if client is invalid
        return msg
    
    def handleError(self, error):
        # something went wrong, kill client connection
        self.transport.loseConnection()
    
    def sendMsg(self, msg):
        self.transport.write(msg)
    

    【讨论】:

    • 与我的第 3 方模块进行通信的最佳方式是什么?我在我的主模块中调用 reactor.listenTCP(...) 。我可以传递参数,但这只能发生一次?我应该使用类似 callFromThread 的东西吗?
    • “与您的 3rd 方模块进行通信的最佳方式”取决于您的 3rd 方模块,您没有说明它是什么和/或它做什么;)。 I can pass in arguments, but this can only happen once? 通常connectionMade 只被调用一次,它不是由你完成的。 Twisted 再次调用此函数来确认客户端 TCP 连接。如果您之后需要发送一条消息,那么您可以使用另一个函数或延迟发送。 callFromThread 可能有用,具体取决于您使用的 gui 模块,但我认为我们可以在很大程度上避免线程
    • 我想我的问题是如何将消息从另一个模块传递给函数thirdPartyComm?上面的延迟代码似乎只在建立连接时运行一次?我需要在单击按钮时发生回调(我正在使用 PyQt)。我可以访问协议类中的函数并直接使用 self.transport.write(msg) 发送消息而不使用 deferred,但是当我这样做时我在 dataReceived(self, data) 中没有得到任何东西。
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2012-09-10
    • 2018-01-03
    • 2019-01-15
    相关资源
    最近更新 更多